##// END OF EJS Templates
wireproto: fix decodelist to properly return empty list...
wireproto: fix decodelist to properly return empty list Needed by tests for next patch introducing known().

File last commit:

r13663:d16c99f1 default
r13722:f4a85ace default
Show More
bookmarks.py
204 lines | 5.8 KiB | text/x-python | PythonLexer
Matt Mackall
bookmarks: move basic io to core
r13350 # Mercurial bookmark support code
#
# Copyright 2008 David Soria Parra <dsp@php.net>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from mercurial.i18n import _
from mercurial.node import nullid, nullrev, bin, hex, short
David Soria Parra
bookmarks: forbid \0 \r \n : in bookmark names (BC)...
r13425 from mercurial import encoding, util
Matt Mackall
bookmarks: move basic io to core
r13350 import os
David Soria Parra
bookmarks: forbid \0 \r \n : in bookmark names (BC)...
r13425 def valid(mark):
for c in (':', '\0', '\n', '\r'):
if c in mark:
return False
return True
Matt Mackall
bookmarks: move read methods to core
r13351 def read(repo):
'''Parse .hg/bookmarks file and return a dictionary
Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values
in the .hg/bookmarks file.
Read the file and return a (name=>nodeid) dictionary
'''
try:
bookmarks = {}
for line in repo.opener('bookmarks'):
sha, refspec = line.strip().split(' ', 1)
refspec = encoding.tolocal(refspec)
bookmarks[refspec] = repo.changelog.lookup(sha)
except:
pass
return bookmarks
def readcurrent(repo):
'''Get the current bookmark
If we use gittishsh branches we have a current bookmark that
we are on. This function returns the name of the bookmark. It
is stored in .hg/bookmarks.current
'''
mark = None
if os.path.exists(repo.join('bookmarks.current')):
file = repo.opener('bookmarks.current')
# No readline() in posixfile_nt, reading everything is cheap
David Soria Parra
bookmarks: read current bookmark as utf-8 and convert it to local
r13381 mark = encoding.tolocal((file.readlines() or [''])[0])
Benoit Boissinot
bookmarks: discard current bookmark if absent from the bookmarks (issue2692)...
r13627 if mark == '' or mark not in repo._bookmarks:
Matt Mackall
bookmarks: move read methods to core
r13351 mark = None
file.close()
return mark
Matt Mackall
bookmarks: move basic io to core
r13350 def write(repo):
'''Write bookmarks
Write the given bookmark => hash dictionary to the .hg/bookmarks file
in a format equal to those of localtags.
We also store a backup of the previous state in undo.bookmarks that
can be copied back on rollback.
'''
refs = repo._bookmarks
try:
bms = repo.opener('bookmarks').read()
except IOError:
bms = ''
repo.opener('undo.bookmarks', 'w').write(bms)
if repo._bookmarkcurrent not in refs:
setcurrent(repo, None)
David Soria Parra
bookmarks: forbid \0 \r \n : in bookmark names (BC)...
r13425 for mark in refs.keys():
if not valid(mark):
raise util.Abort(_("bookmark '%s' contains illegal "
"character" % mark))
Matt Mackall
bookmarks: move basic io to core
r13350 wlock = repo.wlock()
try:
David Soria Parra
bookmarks: forbid \0 \r \n : in bookmark names (BC)...
r13425
Matt Mackall
bookmarks: move basic io to core
r13350 file = repo.opener('bookmarks', 'w', atomictemp=True)
for refspec, node in refs.iteritems():
file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
file.rename()
# touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
try:
os.utime(repo.sjoin('00changelog.i'), None)
except OSError:
pass
finally:
wlock.release()
def setcurrent(repo, mark):
'''Set the name of the bookmark that we are currently on
Set the name of the bookmark that we are on (hg update <bookmark>).
The name is recorded in .hg/bookmarks.current
'''
current = repo._bookmarkcurrent
if current == mark:
return
David Soria Parra
bookmarks: remove API limitation in setcurrent...
r13647 if mark not in repo._bookmarks:
Matt Mackall
bookmarks: move basic io to core
r13350 mark = ''
David Soria Parra
bookmarks: forbid \0 \r \n : in bookmark names (BC)...
r13425 if not valid(mark):
raise util.Abort(_("bookmark '%s' contains illegal "
"character" % mark))
Matt Mackall
bookmarks: move basic io to core
r13350 wlock = repo.wlock()
try:
file = repo.opener('bookmarks.current', 'w', atomictemp=True)
file.write(mark)
file.rename()
finally:
wlock.release()
repo._bookmarkcurrent = mark
Matt Mackall
bookmarks: move update into core
r13352
David Soria Parra
bundle: update current bookmark to most recent revision on current branch...
r13663 def updatecurrentbookmark(repo, oldnode, curbranch):
try:
update(repo, oldnode, repo.branchtags()[curbranch])
except KeyError:
if curbranch == "default": # no default branch!
update(repo, oldnode, repo.lookup("tip"))
else:
raise util.Abort(_("branch %s not found") % curbranch)
Matt Mackall
bookmarks: move update into core
r13352 def update(repo, parents, node):
marks = repo._bookmarks
update = False
David Soria Parra
bookmarks: make track.current=True default behaviour and remove option (BC)
r13416 mark = repo._bookmarkcurrent
if mark and marks[mark] in parents:
David Soria Parra
bookmarks: restrict moving a bookmark to its descendants (issue1502)...
r13478 old = repo[marks[mark]]
new = repo[node]
if new in old.descendants():
marks[mark] = new.node()
update = True
Matt Mackall
bookmarks: move update into core
r13352 if update:
write(repo)
Matt Mackall
bookmarks: move pushkey functions into core
r13353
def listbookmarks(repo):
# We may try to list bookmarks on a repo type that does not
# support it (e.g., statichttprepository).
if not hasattr(repo, '_bookmarks'):
return {}
d = {}
for k, v in repo._bookmarks.iteritems():
d[k] = hex(v)
return d
def pushbookmark(repo, key, old, new):
w = repo.wlock()
try:
marks = repo._bookmarks
if hex(marks.get(key, '')) != old:
return False
if new == '':
del marks[key]
else:
if new not in repo:
return False
marks[key] = repo[new].node()
write(repo)
return True
finally:
w.release()
Matt Mackall
bookmarks: move diff to core
r13354
David Soria Parra
bookmarks: separate bookmarks update code from localrepo's pull....
r13646 def updatefromremote(ui, repo, remote):
ui.debug("checking for updated bookmarks\n")
rb = remote.listkeys('bookmarks')
changed = False
for k in rb.keys():
if k in repo._bookmarks:
nr, nl = rb[k], repo._bookmarks[k]
if nr in repo:
cr = repo[nr]
cl = repo[nl]
if cl.rev() >= cr.rev():
continue
if cr in cl.descendants():
repo._bookmarks[k] = cr.node()
changed = True
ui.status(_("updating bookmark %s\n") % k)
else:
ui.warn(_("not updating divergent"
" bookmark %s\n") % k)
if changed:
write(repo)
Matt Mackall
bookmarks: move diff to core
r13354 def diff(ui, repo, remote):
ui.status(_("searching for changed bookmarks\n"))
lmarks = repo.listkeys('bookmarks')
rmarks = remote.listkeys('bookmarks')
diff = sorted(set(rmarks) - set(lmarks))
for k in diff:
ui.write(" %-25s %s\n" % (k, rmarks[k][:12]))
if len(diff) <= 0:
ui.status(_("no changed bookmarks found\n"))
return 1
return 0