[PATCH 1 of 8 v2] bookmarks: move bookmarks to core
David Soria Parra
dsp at php.net
Tue Feb 1 16:21:53 CST 2011
# HG changeset patch
# User David Soria Parra <dsp at php.net>
# Date 1296598799 -3600
# Node ID f98c0ab906e7165565b6f4380e7a1fe7a54c898e
# Parent 0d1dca7d2a041cb1cb6c6bd90608aa87068bde02
bookmarks: move bookmarks to core
diff --git a/hgext/bookmarks.py b/hgext/bookmarks.py
deleted file mode 100644
--- a/hgext/bookmarks.py
+++ /dev/null
@@ -1,581 +0,0 @@
-# Mercurial extension to provide the 'hg bookmark' command
-#
-# Copyright 2008 David Soria Parra <dsp at 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.
-
-'''track a line of development with movable markers
-
-Bookmarks are local movable markers to changesets. Every bookmark
-points to a changeset identified by its hash. If you commit a
-changeset that is based on a changeset that has a bookmark on it, the
-bookmark shifts to the new changeset.
-
-It is possible to use bookmark names in every revision lookup (e.g.
-:hg:`merge`, :hg:`update`).
-
-By default, when several bookmarks point to the same changeset, they
-will all move forward together. It is possible to obtain a more
-git-like experience by adding the following configuration option to
-your configuration file::
-
- [bookmarks]
- track.current = True
-
-This will cause Mercurial to track the bookmark that you are currently
-using, and only update it. This is similar to git's approach to
-branching.
-'''
-
-from mercurial.i18n import _
-from mercurial.node import nullid, nullrev, bin, hex, short
-from mercurial import util, commands, repair, extensions, pushkey, hg, url
-from mercurial import revset, encoding
-import os
-
-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)
- wlock = repo.wlock()
- try:
- 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
-
- refs = repo._bookmarks
-
- # do not update if we do update to a rev equal to the current bookmark
- if (mark and mark not in refs and
- current and refs[current] == repo.changectx('.').node()):
- return
- if mark not in refs:
- mark = ''
- wlock = repo.wlock()
- try:
- file = repo.opener('bookmarks.current', 'w', atomictemp=True)
- file.write(mark)
- file.rename()
- finally:
- wlock.release()
- repo._bookmarkcurrent = mark
-
-def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False, rename=None):
- '''track a line of development with movable markers
-
- Bookmarks are pointers to certain commits that move when
- committing. Bookmarks are local. They can be renamed, copied and
- deleted. It is possible to use bookmark names in :hg:`merge` and
- :hg:`update` to merge and update respectively to a given bookmark.
-
- You can use :hg:`bookmark NAME` to set a bookmark on the working
- directory's parent revision with the given name. If you specify
- a revision using -r REV (where REV may be an existing bookmark),
- the bookmark is assigned to that revision.
-
- Bookmarks can be pushed and pulled between repositories (see :hg:`help
- push` and :hg:`help pull`). This requires the bookmark extension to be
- enabled for both the local and remote repositories.
- '''
- hexfn = ui.debugflag and hex or short
- marks = repo._bookmarks
- cur = repo.changectx('.').node()
-
- if rename:
- if rename not in marks:
- raise util.Abort(_("a bookmark of this name does not exist"))
- if mark in marks and not force:
- raise util.Abort(_("a bookmark of the same name already exists"))
- if mark is None:
- raise util.Abort(_("new bookmark name required"))
- marks[mark] = marks[rename]
- del marks[rename]
- if repo._bookmarkcurrent == rename:
- setcurrent(repo, mark)
- write(repo)
- return
-
- if delete:
- if mark is None:
- raise util.Abort(_("bookmark name required"))
- if mark not in marks:
- raise util.Abort(_("a bookmark of this name does not exist"))
- if mark == repo._bookmarkcurrent:
- setcurrent(repo, None)
- del marks[mark]
- write(repo)
- return
-
- if mark is not None:
- if "\n" in mark:
- raise util.Abort(_("bookmark name cannot contain newlines"))
- mark = mark.strip()
- if not mark:
- raise util.Abort(_("bookmark names cannot consist entirely of "
- "whitespace"))
- if mark in marks and not force:
- raise util.Abort(_("a bookmark of the same name already exists"))
- if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
- and not force):
- raise util.Abort(
- _("a bookmark cannot have the name of an existing branch"))
- if rev:
- marks[mark] = repo.lookup(rev)
- else:
- marks[mark] = repo.changectx('.').node()
- setcurrent(repo, mark)
- write(repo)
- return
-
- if mark is None:
- if rev:
- raise util.Abort(_("bookmark name required"))
- if len(marks) == 0:
- ui.status(_("no bookmarks set\n"))
- else:
- for bmark, n in marks.iteritems():
- if ui.configbool('bookmarks', 'track.current'):
- current = repo._bookmarkcurrent
- if bmark == current and n == cur:
- prefix, label = '*', 'bookmarks.current'
- else:
- prefix, label = ' ', ''
- else:
- if n == cur:
- prefix, label = '*', 'bookmarks.current'
- else:
- prefix, label = ' ', ''
-
- if ui.quiet:
- ui.write("%s\n" % bmark, label=label)
- else:
- ui.write(" %s %-25s %d:%s\n" % (
- prefix, bmark, repo.changelog.rev(n), hexfn(n)),
- label=label)
- return
-
-def _revstostrip(changelog, node):
- srev = changelog.rev(node)
- tostrip = [srev]
- saveheads = []
- for r in xrange(srev, len(changelog)):
- parents = changelog.parentrevs(r)
- if parents[0] in tostrip or parents[1] in tostrip:
- tostrip.append(r)
- if parents[1] != nullrev:
- for p in parents:
- if p not in tostrip and p > srev:
- saveheads.append(p)
- return [r for r in tostrip if r not in saveheads]
-
-def strip(oldstrip, ui, repo, node, backup="all"):
- """Strip bookmarks if revisions are stripped using
- the mercurial.strip method. This usually happens during
- qpush and qpop"""
- revisions = _revstostrip(repo.changelog, node)
- marks = repo._bookmarks
- update = []
- for mark, n in marks.iteritems():
- if repo.changelog.rev(n) in revisions:
- update.append(mark)
- oldstrip(ui, repo, node, backup)
- if len(update) > 0:
- for m in update:
- marks[m] = repo.changectx('.').node()
- write(repo)
-
-def reposetup(ui, repo):
- if not repo.local():
- return
-
- class bookmark_repo(repo.__class__):
-
- @util.propertycache
- def _bookmarks(self):
- '''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 self.opener('bookmarks'):
- sha, refspec = line.strip().split(' ', 1)
- refspec = encoding.tolocal(refspec)
- bookmarks[refspec] = self.changelog.lookup(sha)
- except:
- pass
- return bookmarks
-
- @util.propertycache
- def _bookmarkcurrent(self):
- '''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(self.join('bookmarks.current')):
- file = self.opener('bookmarks.current')
- # No readline() in posixfile_nt, reading everything is cheap
- mark = (file.readlines() or [''])[0]
- if mark == '':
- mark = None
- file.close()
- return mark
-
- def rollback(self, dryrun=False):
- if os.path.exists(self.join('undo.bookmarks')):
- if not dryrun:
- util.rename(self.join('undo.bookmarks'), self.join('bookmarks'))
- elif not os.path.exists(self.sjoin("undo")):
- # avoid "no rollback information available" message
- return 0
- return super(bookmark_repo, self).rollback(dryrun)
-
- def lookup(self, key):
- if key in self._bookmarks:
- key = self._bookmarks[key]
- return super(bookmark_repo, self).lookup(key)
-
- def _bookmarksupdate(self, parents, node):
- marks = self._bookmarks
- update = False
- if ui.configbool('bookmarks', 'track.current'):
- mark = self._bookmarkcurrent
- if mark and marks[mark] in parents:
- marks[mark] = node
- update = True
- else:
- for mark, n in marks.items():
- if n in parents:
- marks[mark] = node
- update = True
- if update:
- write(self)
-
- def commitctx(self, ctx, error=False):
- """Add a revision to the repository and
- move the bookmark"""
- wlock = self.wlock() # do both commit and bookmark with lock held
- try:
- node = super(bookmark_repo, self).commitctx(ctx, error)
- if node is None:
- return None
- parents = self.changelog.parents(node)
- if parents[1] == nullid:
- parents = (parents[0],)
-
- self._bookmarksupdate(parents, node)
- return node
- finally:
- wlock.release()
-
- def pull(self, remote, heads=None, force=False):
- result = super(bookmark_repo, self).pull(remote, heads, force)
-
- self.ui.debug("checking for updated bookmarks\n")
- rb = remote.listkeys('bookmarks')
- changed = False
- for k in rb.keys():
- if k in self._bookmarks:
- nr, nl = rb[k], self._bookmarks[k]
- if nr in self:
- cr = self[nr]
- cl = self[nl]
- if cl.rev() >= cr.rev():
- continue
- if cr in cl.descendants():
- self._bookmarks[k] = cr.node()
- changed = True
- self.ui.status(_("updating bookmark %s\n") % k)
- else:
- self.ui.warn(_("not updating divergent"
- " bookmark %s\n") % k)
- if changed:
- write(repo)
-
- return result
-
- def push(self, remote, force=False, revs=None, newbranch=False):
- result = super(bookmark_repo, self).push(remote, force, revs,
- newbranch)
-
- self.ui.debug("checking for updated bookmarks\n")
- rb = remote.listkeys('bookmarks')
- for k in rb.keys():
- if k in self._bookmarks:
- nr, nl = rb[k], hex(self._bookmarks[k])
- if nr in self:
- cr = self[nr]
- cl = self[nl]
- if cl in cr.descendants():
- r = remote.pushkey('bookmarks', k, nr, nl)
- if r:
- self.ui.status(_("updating bookmark %s\n") % k)
- else:
- self.ui.warn(_('updating bookmark %s'
- ' failed!\n') % k)
-
- return result
-
- def addchangegroup(self, *args, **kwargs):
- result = super(bookmark_repo, self).addchangegroup(*args, **kwargs)
- if result > 1:
- # We have more heads than before
- return result
- node = self.changelog.tip()
- parents = self.dirstate.parents()
- self._bookmarksupdate(parents, node)
- return result
-
- def _findtags(self):
- """Merge bookmarks with normal tags"""
- (tags, tagtypes) = super(bookmark_repo, self)._findtags()
- tags.update(self._bookmarks)
- return (tags, tagtypes)
-
- if hasattr(repo, 'invalidate'):
- def invalidate(self):
- super(bookmark_repo, self).invalidate()
- for attr in ('_bookmarks', '_bookmarkcurrent'):
- if attr in self.__dict__:
- delattr(self, attr)
-
- repo.__class__ = bookmark_repo
-
-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()
-
-def pull(oldpull, ui, repo, source="default", **opts):
- # translate bookmark args to rev args for actual pull
- if opts.get('bookmark'):
- # this is an unpleasant hack as pull will do this internally
- source, branches = hg.parseurl(ui.expandpath(source),
- opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), source)
- rb = other.listkeys('bookmarks')
-
- for b in opts['bookmark']:
- if b not in rb:
- raise util.Abort(_('remote bookmark %s not found!') % b)
- opts.setdefault('rev', []).append(b)
-
- result = oldpull(ui, repo, source, **opts)
-
- # update specified bookmarks
- if opts.get('bookmark'):
- for b in opts['bookmark']:
- # explicit pull overrides local bookmark if any
- ui.status(_("importing bookmark %s\n") % b)
- repo._bookmarks[b] = repo[rb[b]].node()
- write(repo)
-
- return result
-
-def push(oldpush, ui, repo, dest=None, **opts):
- dopush = True
- if opts.get('bookmark'):
- dopush = False
- for b in opts['bookmark']:
- if b in repo._bookmarks:
- dopush = True
- opts.setdefault('rev', []).append(b)
-
- result = 0
- if dopush:
- result = oldpush(ui, repo, dest, **opts)
-
- if opts.get('bookmark'):
- # this is an unpleasant hack as push will do this internally
- dest = ui.expandpath(dest or 'default-push', dest or 'default')
- dest, branches = hg.parseurl(dest, opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), dest)
- rb = other.listkeys('bookmarks')
- for b in opts['bookmark']:
- # explicit push overrides remote bookmark if any
- if b in repo._bookmarks:
- ui.status(_("exporting bookmark %s\n") % b)
- new = repo[b].hex()
- elif b in rb:
- ui.status(_("deleting remote bookmark %s\n") % b)
- new = '' # delete
- else:
- ui.warn(_('bookmark %s does not exist on the local '
- 'or remote repository!\n') % b)
- return 2
- old = rb.get(b, '')
- r = other.pushkey('bookmarks', b, old, new)
- if not r:
- ui.warn(_('updating bookmark %s failed!\n') % b)
- if not result:
- result = 2
-
- return result
-
-def diffbookmarks(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
-
-def incoming(oldincoming, ui, repo, source="default", **opts):
- if opts.get('bookmarks'):
- source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), source)
- ui.status(_('comparing with %s\n') % url.hidepassword(source))
- return diffbookmarks(ui, repo, other)
- else:
- return oldincoming(ui, repo, source, **opts)
-
-def outgoing(oldoutgoing, ui, repo, dest=None, **opts):
- if opts.get('bookmarks'):
- dest = ui.expandpath(dest or 'default-push', dest or 'default')
- dest, branches = hg.parseurl(dest, opts.get('branch'))
- other = hg.repository(hg.remoteui(repo, opts), dest)
- ui.status(_('comparing with %s\n') % url.hidepassword(dest))
- return diffbookmarks(ui, other, repo)
- else:
- return oldoutgoing(ui, repo, dest, **opts)
-
-def uisetup(ui):
- extensions.wrapfunction(repair, "strip", strip)
- if ui.configbool('bookmarks', 'track.current'):
- extensions.wrapcommand(commands.table, 'update', updatecurbookmark)
-
- entry = extensions.wrapcommand(commands.table, 'pull', pull)
- entry[1].append(('B', 'bookmark', [],
- _("bookmark to import"),
- _('BOOKMARK')))
- entry = extensions.wrapcommand(commands.table, 'push', push)
- entry[1].append(('B', 'bookmark', [],
- _("bookmark to export"),
- _('BOOKMARK')))
- entry = extensions.wrapcommand(commands.table, 'incoming', incoming)
- entry[1].append(('B', 'bookmarks', False,
- _("compare bookmark")))
- entry = extensions.wrapcommand(commands.table, 'outgoing', outgoing)
- entry[1].append(('B', 'bookmarks', False,
- _("compare bookmark")))
-
- pushkey.register('bookmarks', pushbookmark, listbookmarks)
-
-def updatecurbookmark(orig, ui, repo, *args, **opts):
- '''Set the current bookmark
-
- If the user updates to a bookmark we update the .hg/bookmarks.current
- file.
- '''
- res = orig(ui, repo, *args, **opts)
- rev = opts['rev']
- if not rev and len(args) > 0:
- rev = args[0]
- setcurrent(repo, rev)
- return res
-
-def bmrevset(repo, subset, x):
- """``bookmark([name])``
- The named bookmark or all bookmarks.
- """
- # i18n: "bookmark" is a keyword
- args = revset.getargs(x, 0, 1, _('bookmark takes one or no arguments'))
- if args:
- bm = revset.getstring(args[0],
- # i18n: "bookmark" is a keyword
- _('the argument to bookmark must be a string'))
- bmrev = listbookmarks(repo).get(bm, None)
- if bmrev:
- bmrev = repo.changelog.rev(bin(bmrev))
- return [r for r in subset if r == bmrev]
- bms = set([repo.changelog.rev(bin(r)) for r in listbookmarks(repo).values()])
- return [r for r in subset if r in bms]
-
-def extsetup(ui):
- revset.symbols['bookmark'] = bmrevset
-
-cmdtable = {
- "bookmarks":
- (bookmark,
- [('f', 'force', False, _('force')),
- ('r', 'rev', '', _('revision'), _('REV')),
- ('d', 'delete', False, _('delete a given bookmark')),
- ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
- _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
-}
-
-colortable = {'bookmarks.current': 'green'}
-
-# tell hggettext to extract docstrings from these functions:
-i18nfunctions = [bmrevset]
diff --git a/hgext/color.py b/hgext/color.py
--- a/hgext/color.py
+++ b/hgext/color.py
@@ -96,6 +96,7 @@
'branches.closed': 'black bold',
'branches.current': 'green',
'branches.inactive': 'none',
+ 'bookmarks.current': 'green',
'diff.changed': 'white',
'diff.deleted': 'red',
'diff.diffline': 'bold',
diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py
new file mode 100644
--- /dev/null
+++ b/mercurial/bookmarks.py
@@ -0,0 +1,52 @@
+# bookmarks.py - pushkey functions for bookmarks
+#
+# Copyright 2010 David Soria Parra <dsp at 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 node import hex
+from i18n import _
+import pushkey
+
+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()
+ repo.bookmarkswrite()
+ return True
+ finally:
+ w.release()
+
+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 diffbookmarks(ui, repo, other):
+ ui.status(_("searching for changed bookmarks\n"))
+
+ lmarks = repo.listkeys('bookmarks')
+ rmarks = other.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
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -14,7 +14,7 @@
import archival, changegroup, cmdutil, sshserver, hbisect, hgweb, hgweb.server
import merge as mergemod
import minirst, revset
-import dagparser
+import dagparser, bookmarks
# Commands start here, listed alphabetically
@@ -461,6 +461,100 @@
cmdutil.bail_if_changed(repo)
return hg.clean(repo, node)
+def bookmark(ui, repo, mark=None, rev=None, force=False, delete=False,
+ rename=None):
+ '''track a line of development with movable markers
+
+ Bookmarks are pointers to certain commits that move when
+ committing. They can be renamed, copied and
+ deleted. It is possible to use bookmark names in :hg:`merge` and
+ :hg:`update` to merge and update respectively to a given bookmark.
+
+ You can use :hg:`bookmark NAME` to set a bookmark on the working
+ directory's parent revision with the given name. If you specify
+ a revision using -r REV (where REV may be an existing bookmark),
+ the bookmark is assigned to that revision.
+
+ Bookmarks can be pushed between repositories (see :hg:`help
+ push`). Remote bookmarks that match a local name will be forwarded
+ on pull.
+ '''
+ hexfn = ui.debugflag and hex or short
+ cur = repo.changectx('.').node()
+
+ if rename:
+ if rename not in repo.bookmarks:
+ raise util.Abort(_("a bookmark of this name does not exist"))
+ if mark in repo.bookmarks and not force:
+ raise util.Abort(_("a bookmark of the same name already exists"))
+ if mark is None:
+ raise util.Abort(_("new bookmark name required"))
+ repo.bookmarks[mark] = repo.bookmarks[rename]
+ del repo.bookmarks[rename]
+ if repo.bookmarkcurrent == rename:
+ repo.bookmarksetcurrent(mark)
+ repo.bookmarkswrite()
+ return
+
+ if delete:
+ if mark is None:
+ raise util.Abort(_("bookmark name required"))
+ if mark not in repo.bookmarks:
+ raise util.Abort(_("a bookmark of this name does not exist"))
+ if mark == repo.bookmarkcurrent:
+ repo.bookmarksetcurrent(None)
+ del repo.bookmarks[mark]
+ repo.bookmarkswrite()
+ return
+
+ if mark is not None:
+ if "\n" in mark:
+ raise util.Abort(_("bookmark name cannot contain newlines"))
+ mark = mark.strip()
+ if not mark:
+ raise util.Abort(_("bookmark names cannot consist entirely of "
+ "whitespace"))
+ if mark in repo.bookmarks and not force:
+ raise util.Abort(_("a bookmark of the same name already exists"))
+ if ((mark in repo.branchtags() or mark == repo.dirstate.branch())
+ and not force):
+ raise util.Abort(
+ _("a bookmark cannot have the name of an existing branch"))
+ if rev:
+ repo.bookmarks[mark] = repo.lookup(rev)
+ else:
+ repo.bookmarks[mark] = repo.changectx('.').node()
+ repo.bookmarksetcurrent(mark)
+ repo.bookmarkswrite()
+ return
+
+ if mark is None:
+ if rev:
+ raise util.Abort(_("bookmark name required"))
+ if len(repo.bookmarks) == 0:
+ ui.status(_("no bookmarks set\n"))
+ else:
+ for bmark, n in repo.bookmarks.iteritems():
+ if ui.configbool('bookmarks', 'track.current'):
+ current = repo.bookmarkcurrent
+ if bmark == current and n == cur:
+ prefix, label = '*', 'bookmarks.current'
+ else:
+ prefix, label = ' ', ''
+ else:
+ if n == cur:
+ prefix, label = '*', 'bookmarks.current'
+ else:
+ prefix, label = ' ', ''
+
+ if ui.quiet:
+ ui.write("%s\n" % bmark, label=label)
+ else:
+ ui.write(" %s %-25s %d:%s\n" % (
+ prefix, bmark, repo.changelog.rev(n), hexfn(n)),
+ label=label)
+ return
+
def branch(ui, repo, label=None, **opts):
"""set or show the current branch name
@@ -2403,7 +2497,13 @@
if opts.get('bundle') and opts.get('subrepos'):
raise util.Abort(_('cannot combine --bundle and --subrepos'))
- ret = hg.incoming(ui, repo, source, opts)
+ if opts.get("bookmarks"):
+ source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
+ other = hg.repository(hg.remoteui(repo, opts), source)
+ ui.status(_('comparing with %s\n') % url.hidepassword(source))
+ return bookmarks.diffbookmarks(ui, repo, other)
+ else:
+ ret = hg.incoming(ui, repo, source, opts)
return ret
def init(ui, dest=".", **opts):
@@ -2679,7 +2779,14 @@
Returns 0 if there are outgoing changes, 1 otherwise.
"""
- ret = hg.outgoing(ui, repo, dest, opts)
+ if opts.get("bookmarks"):
+ dest = ui.expandpath(dest or 'default-push', dest or 'default')
+ dest, branches = hg.parseurl(dest, opts.get('branch'))
+ other = hg.repository(hg.remoteui(repo, opts), dest)
+ ui.status(_('comparing with %s\n') % url.hidepassword(dest))
+ return bookmarks.diffbookmarks(ui, other, repo)
+ else:
+ ret = hg.outgoing(ui, repo, dest, opts)
return ret
def parents(ui, repo, file_=None, **opts):
@@ -2793,6 +2900,14 @@
"""
source, branches = hg.parseurl(ui.expandpath(source), opts.get('branch'))
other = hg.repository(hg.remoteui(repo, opts), source)
+
+ if opts.get('bookmark'):
+ rb = other.listkeys('bookmarks')
+ for b in opts['bookmark']:
+ if b not in rb:
+ raise util.Abort(_('remote bookmark %s not found!') % b)
+ opts.setdefault('rev', []).append(b)
+
ui.status(_('pulling from %s\n') % url.hidepassword(source))
revs, checkout = hg.addbranchrevs(repo, other, branches, opts.get('rev'))
if revs:
@@ -2804,6 +2919,15 @@
raise util.Abort(err)
modheads = repo.pull(other, heads=revs, force=opts.get('force'))
+
+ # update specified bookmarks
+ if opts.get('bookmark'):
+ for b in opts['bookmark']:
+ # explicit pull overrides local bookmark if any
+ ui.status(_("importing bookmark %s\n") % b)
+ repo.bookmarks[b] = repo[rb[b]].node()
+ repo.bookmarkswrite()
+
if checkout:
checkout = str(repo.changelog.rev(other.lookup(checkout)))
repo._subtoppath = source
@@ -2845,22 +2969,55 @@
dest, branches = hg.parseurl(dest, opts.get('branch'))
revs, checkout = hg.addbranchrevs(repo, repo, branches, opts.get('rev'))
other = hg.repository(hg.remoteui(repo, opts), dest)
- ui.status(_('pushing to %s\n') % url.hidepassword(dest))
- if revs:
- revs = [repo.lookup(rev) for rev in revs]
-
- repo._subtoppath = dest
- try:
- # push subrepos depth-first for coherent ordering
- c = repo['']
- subs = c.substate # only repos that are committed
- for s in sorted(subs):
- if not c.sub(s).push(opts.get('force')):
- return False
- finally:
- del repo._subtoppath
- r = repo.push(other, opts.get('force'), revs=revs,
- newbranch=opts.get('new_branch'))
+
+ dopush = True
+ if opts.get('bookmark'):
+ dopush = False
+ for b in opts['bookmark']:
+ if b in repo.bookmarks:
+ dopush = True
+ opts.setdefault('rev', []).append(b)
+
+ r = -1
+ if dopush:
+ ui.status(_('pushing to %s\n') % url.hidepassword(dest))
+ if revs:
+ revs = [repo.lookup(rev) for rev in revs]
+
+ repo._subtoppath = dest
+ try:
+ # push subrepos depth-first for coherent ordering
+ c = repo['']
+ subs = c.substate # only repos that are committed
+ for s in sorted(subs):
+ if not c.sub(s).push(opts.get('force')):
+ return False
+ finally:
+ del repo._subtoppath
+
+ r = repo.push(other, opts.get('force'), revs=revs,
+ newbranch=opts.get('new_branch'))
+
+ if opts.get('bookmark'):
+ rb = other.listkeys('bookmarks')
+ for b in opts['bookmark']:
+ # explicit push overrides remote bookmark if any
+ if b in repo.bookmarks:
+ ui.status(_("exporting bookmark %s\n") % b)
+ new = repo[b].hex()
+ elif b in rb:
+ ui.status(_("deleting remote bookmark %s\n") % b)
+ new = '' # delete
+ else:
+ ui.warn(_('bookmark %s does not exist on the local '
+ 'or remote repository!\n') % b)
+ return 2
+ old = rb.get(b, '')
+ res = other.pushkey('bookmarks', b, old, new)
+ if not res:
+ ui.warn(_('updating bookmark %s failed!\n') % b)
+ if not r:
+ return 2
return r == 0
def recover(ui, repo):
@@ -3865,6 +4022,7 @@
if not rev:
rev = node
+ mark = rev
rev = cmdutil.revsingle(repo, rev, rev).rev()
if check and clean:
@@ -3882,9 +4040,12 @@
rev = cmdutil.finddate(ui, repo, date)
if clean or check:
- return hg.clean(repo, rev)
+ res = hg.clean(repo, rev)
else:
- return hg.update(repo, rev)
+ res = hg.update(repo, rev)
+ if mark in repo.bookmarks:
+ repo.bookmarksetcurrent(mark)
+ return res
def verify(ui, repo):
"""verify the integrity of the repository
@@ -4063,6 +4224,13 @@
_('revision to backout'), _('REV')),
] + walkopts + commitopts + commitopts2,
_('[OPTION]... [-r] REV')),
+ "bookmarks":
+ (bookmark,
+ [('f', 'force', False, _('force')),
+ ('r', 'rev', '', _('revision'), _('REV')),
+ ('d', 'delete', False, _('delete a given bookmark')),
+ ('m', 'rename', '', _('rename a given bookmark'), _('NAME'))],
+ _('hg bookmarks [-f] [-d] [-m NAME] [-r REV] [NAME]')),
"bisect":
(bisect,
[('r', 'reset', False, _('reset bisect state')),
@@ -4291,6 +4459,8 @@
_('a remote changeset intended to be added'), _('REV')),
('b', 'branch', [],
_('a specific branch you would like to pull'), _('BRANCH')),
+ ('B', 'bookmarks', False,
+ _("compare bookmark")),
] + logopts + remoteopts + subrepoopts,
_('[-p] [-n] [-M] [-f] [-r REV]...'
' [--bundle FILENAME] [SOURCE]')),
@@ -4359,6 +4529,8 @@
('n', 'newest-first', None, _('show newest record first')),
('b', 'branch', [],
_('a specific branch you would like to push'), _('BRANCH')),
+ ('B', 'bookmarks', False,
+ _("compare bookmark")),
] + logopts + remoteopts + subrepoopts,
_('[-M] [-p] [-n] [-f] [-r REV]... [DEST]')),
"parents":
@@ -4378,6 +4550,9 @@
_('a remote changeset intended to be added'), _('REV')),
('b', 'branch', [],
_('a specific branch you would like to pull'), _('BRANCH')),
+ ('B', 'bookmark', [],
+ _("bookmark to import"),
+ _('BOOKMARK')),
] + remoteopts,
_('[-u] [-f] [-r REV]... [-e CMD] [--remotecmd CMD] [SOURCE]')),
"^push":
@@ -4388,6 +4563,9 @@
_('REV')),
('b', 'branch', [],
_('a specific branch you would like to push'), _('BRANCH')),
+ ('B', 'bookmark', [],
+ _("bookmark to export"),
+ _('BOOKMARK')),
('', 'new-branch', False, _('allow pushing a new branch')),
] + remoteopts,
_('[-f] [-r REV]... [-e CMD] [--remotecmd CMD] [DEST]')),
diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
--- a/mercurial/localrepo.py
+++ b/mercurial/localrepo.py
@@ -355,6 +355,7 @@
tags['tip'] = self.changelog.tip()
tagtypes = dict([(encoding.tolocal(name), value)
for (name, value) in tagtypes.iteritems()])
+ tags.update(self.bookmarks)
return (tags, tagtypes)
def tagtype(self, tagname):
@@ -501,7 +502,157 @@
bheads = [b for b in bheads if b not in reachable]
partial[branch] = bheads
+ def _bookmarkspull(self, remote):
+ self.ui.debug("checking for updated bookmarks\n")
+ rb = remote.listkeys('bookmarks')
+ changed = False
+ for k in rb.keys():
+ if k in self.bookmarks:
+ nr, nl = rb[k], self.bookmarks[k]
+ if nr in self:
+ cr = self[nr]
+ cl = self[nl]
+ if cl.rev() >= cr.rev():
+ continue
+ if cr in cl.descendants():
+ self.bookmarks[k] = cr.node()
+ changed = True
+ self.ui.status(_("updating bookmark %s\n") % k)
+ else:
+ self.ui.warn(_("not updating divergent"
+ " bookmark %s\n") % k)
+ if changed:
+ self.bookmarkswrite()
+
+ def _bookmarkspush(self, remote):
+ self.ui.debug("checking for updated bookmarks\n")
+ rb = remote.listkeys('bookmarks')
+ for k in rb.keys():
+ if k in self.bookmarks:
+ nr, nl = rb[k], hex(self.bookmarks[k])
+ if nr in self:
+ cr = self[nr]
+ cl = self[nl]
+ if cl in cr.descendants():
+ r = remote.pushkey('bookmarks', k, nr, nl)
+ if r:
+ self.ui.status(_("updating bookmark %s\n") % k)
+ else:
+ self.ui.warn(_('updating bookmark %s'
+ ' failed!\n') % k)
+
+ def _bookmarksupdate(self, node):
+ parents = self.changelog.parents(node)
+ if parents[1] == nullid:
+ parents = (parents[0],)
+ marks = self.bookmarks
+ update = False
+ if self.ui.configbool('bookmarks', 'track.current'):
+ mark = self.bookmarkcurrent
+ if mark and mark in marks and marks[mark] in parents:
+ marks[mark] = node
+ update = True
+ else:
+ for mark, n in marks.items():
+ if n in parents:
+ marks[mark] = node
+ update = True
+ if update:
+ self.bookmarkswrite()
+
+ @propertycache
+ def bookmarks(self):
+ '''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
+ '''
+ bookmarks = {}
+ if os.path.exists(self.join('bookmarks')):
+ for line in self.opener('bookmarks'):
+ sha, name = line.strip().split(' ', 1)
+ ref = encoding.tolocal(name)
+ bookmarks[ref] = self.changelog.lookup(sha)
+ return bookmarks
+
+ @propertycache
+ def bookmarkcurrent(self):
+ mark = None
+ if os.path.exists(self.join('bookmarks.current')):
+ file = self.opener('bookmarks.current')
+ # No readline() in posixfile_nt, reading everything is cheap
+ mark = (file.readlines() or [''])[0]
+ if mark == '':
+ mark = None
+ file.close()
+ return mark
+
+ def bookmarksetcurrent(self, 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 = self.bookmarkcurrent
+ if current == mark:
+ return
+
+ refs = self.bookmarks
+
+ # do not update if we do update to a rev equal to the current bookmark
+ if (mark and mark not in refs and
+ current and refs[current] == self.changectx('.').node()):
+ return
+ if mark not in refs:
+ mark = ''
+ wlock = self.wlock()
+ try:
+ file = self.opener('bookmarks.current', 'w', atomictemp=True)
+ file.write(mark)
+ file.rename()
+ finally:
+ wlock.release()
+ self.bookmarkcurrent = mark
+
+ def bookmarkswrite(self):
+ '''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 = self.bookmarks
+
+ try:
+ bms = self.opener('bookmarks').read()
+ except IOError:
+ bms = ''
+ self.opener('undo.bookmarks', 'w').write(bms)
+
+ if self.bookmarkcurrent not in refs:
+ self.bookmarksetcurrent(None)
+ wlock = self.wlock()
+ try:
+ file = self.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(self.sjoin('00changelog.i'), None)
+ except OSError:
+ pass
+
+ finally:
+ wlock.release()
+
def lookup(self, key):
+ if key in self.bookmarks:
+ return self.bookmarks[key]
if isinstance(key, int):
return self.changelog.node(key)
elif key == '.':
@@ -692,6 +843,12 @@
try:
wlock = self.wlock()
lock = self.lock()
+ noinfo = True
+ if os.path.exists(self.join('undo.bookmarks')):
+ noinfo = False
+ if not dryrun:
+ util.rename(self.join('undo.bookmarks'),
+ self.join('bookmarks'))
if os.path.exists(self.sjoin("undo")):
try:
args = self.opener("undo.desc", "r").read().splitlines()
@@ -720,7 +877,7 @@
self.invalidate()
self.dirstate.invalidate()
self.destroyed()
- else:
+ elif noinfo:
self.ui.warn(_("no rollback information available\n"))
return 1
finally:
@@ -734,7 +891,7 @@
self._branchcachetip = None
def invalidate(self):
- for a in ("changelog", "manifest"):
+ for a in ("changelog", "manifest", "_bookmarks", "_bookmarkcurrent"):
if a in self.__dict__:
delattr(self, a)
self.invalidatecaches()
@@ -978,6 +1135,9 @@
_('note: commit message saved in %s\n') % msgfn)
raise
+ # update bookmarks
+ self._bookmarksupdate(ret)
+
# update dirstate and mergestate
for f in changes[0] + changes[1]:
self.dirstate.normal(f)
@@ -1301,8 +1461,11 @@
"other repository doesn't support "
"changegroupsubset."))
cg = remote.changegroupsubset(fetch, heads, 'pull')
+
return self.addchangegroup(cg, 'pull', remote.url(), lock=lock)
finally:
+ if remote.capable('pushkey'):
+ self._bookmarkspull(remote)
lock.release()
def push(self, remote, force=False, revs=None, newbranch=False):
@@ -1342,11 +1505,15 @@
remote_heads = ['force']
# ssh: return remote's addchangegroup()
# http: return remote's addchangegroup() or 0 for error
- return remote.unbundle(cg, remote_heads, 'push')
+ ret = remote.unbundle(cg, remote_heads, 'push')
else:
# we return an integer indicating remote head count change
- return remote.addchangegroup(cg, 'push', self.url(), lock=lock)
+ ret = remote.addchangegroup(cg, 'push', self.url(), lock=lock)
+
+ return ret
finally:
+ if remote.capable('pushkey'):
+ self._bookmarkspush(remote)
if lock is not None:
lock.release()
@@ -1827,6 +1994,10 @@
self.hook("incoming", node=hex(cl.node(i)),
source=srctype, url=url)
+ if newheads - oldheads <= 1:
+ node = self.changelog.tip()
+ self._bookmarksupdate(node)
+
# never return 0 here:
if newheads < oldheads:
return newheads - oldheads - 1
diff --git a/mercurial/pushkey.py b/mercurial/pushkey.py
--- a/mercurial/pushkey.py
+++ b/mercurial/pushkey.py
@@ -4,6 +4,7 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
+import bookmarks
def _nslist(repo):
n = {}
@@ -11,7 +12,8 @@
n[k] = ""
return n
-_namespaces = {"namespaces": (lambda *x: False, _nslist)}
+_namespaces = {"namespaces": (lambda *x: False, _nslist),
+ "bookmarks": (bookmarks.pushbookmark, bookmarks.listbookmarks)}
def register(namespace, pushkey, listkeys):
_namespaces[namespace] = (pushkey, listkeys)
diff --git a/mercurial/repair.py b/mercurial/repair.py
--- a/mercurial/repair.py
+++ b/mercurial/repair.py
@@ -105,7 +105,11 @@
saveheads.difference_update(parents)
saveheads.add(r)
+ rmrevs = [cl.node(r) for r in tostrip if r not in saveheads]
saveheads = [cl.node(r) for r in saveheads]
+ # read bookmarks before we strip. or lookups will fail
+ bookmarks = repo.bookmarks
+
files = _collectfiles(repo, striprev)
extranodes = _collectextranodes(repo, files, striprev)
@@ -164,4 +168,13 @@
% chgrpfile)
raise
+ # update bookmarks
+ writebookmarks = False
+ if len(rmrevs) > 0:
+ for mark, n in bookmarks.iteritems():
+ if n in rmrevs:
+ writebookmarks = True
+ repo.bookmarks[mark] = repo.changectx('.').node()
+ if writebookmarks:
+ repo.bookmarkswrite()
repo.destroyed()
diff --git a/mercurial/revset.py b/mercurial/revset.py
--- a/mercurial/revset.py
+++ b/mercurial/revset.py
@@ -9,6 +9,7 @@
import parser, util, error, discovery
import match as matchmod
from i18n import _, gettext
+from mercurial.node import hex, bin
elements = {
"(": (20, ("group", 1, ")"), ("func", 1, ")")),
@@ -664,6 +665,33 @@
def tagged(repo, subset, x):
return tag(repo, subset, x)
+def bookmark(repo, subset, x):
+ """``bookmark([name])``
+ The named bookmark or all bookmarks.
+ """
+ # i18n: "bookmark" is a keyword
+ 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
+ args = getargs(x, 0, 1, _('bookmark takes one or no arguments'))
+ if args:
+ bm = getstring(args[0],
+ # i18n: "bookmark" is a keyword
+ _('the argument to bookmark must be a string'))
+ bmrev = listbookmarks(repo).get(bm, None)
+ if bmrev:
+ bmrev = repo.changelog.rev(bin(bmrev))
+ return [r for r in subset if r == bmrev]
+ bms = [repo.changelog.rev(bin(r)) for r in listbookmarks(repo).values()]
+ return [r for r in subset if r in set(bms)]
+
symbols = {
"adds": adds,
"all": getall,
@@ -671,6 +699,7 @@
"ancestors": ancestors,
"author": author,
"branch": branch,
+ "bookmark": bookmark,
"children": children,
"closed": closed,
"contains": contains,
diff --git a/tests/test-bookmarks-current.t b/tests/test-bookmarks-current.t
--- a/tests/test-bookmarks-current.t
+++ b/tests/test-bookmarks-current.t
@@ -1,6 +1,3 @@
- $ echo "[extensions]" >> $HGRCPATH
- $ echo "bookmarks=" >> $HGRCPATH
-
$ echo "[bookmarks]" >> $HGRCPATH
$ echo "track.current = True" >> $HGRCPATH
diff --git a/tests/test-bookmarks-pushpull.t b/tests/test-bookmarks-pushpull.t
--- a/tests/test-bookmarks-pushpull.t
+++ b/tests/test-bookmarks-pushpull.t
@@ -1,6 +1,3 @@
- $ echo "[extensions]" >> $HGRCPATH
- $ echo "bookmarks=" >> $HGRCPATH
-
$ echo "[bookmarks]" >> $HGRCPATH
$ echo "track.current = True" >> $HGRCPATH
diff --git a/tests/test-bookmarks-rebase.t b/tests/test-bookmarks-rebase.t
--- a/tests/test-bookmarks-rebase.t
+++ b/tests/test-bookmarks-rebase.t
@@ -1,6 +1,5 @@
$ echo "[extensions]" >> $HGRCPATH
$ echo "rebase=" >> $HGRCPATH
- $ echo "bookmarks=" >> $HGRCPATH
initialize repository
diff --git a/tests/test-bookmarks-strip.t b/tests/test-bookmarks-strip.t
--- a/tests/test-bookmarks-strip.t
+++ b/tests/test-bookmarks-strip.t
@@ -1,5 +1,4 @@
$ echo "[extensions]" >> $HGRCPATH
- $ echo "bookmarks=" >> $HGRCPATH
$ echo "mq=" >> $HGRCPATH
$ hg init
diff --git a/tests/test-bookmarks.t b/tests/test-bookmarks.t
--- a/tests/test-bookmarks.t
+++ b/tests/test-bookmarks.t
@@ -1,6 +1,3 @@
- $ echo "[extensions]" >> $HGRCPATH
- $ echo "bookmarks=" >> $HGRCPATH
-
$ hg init
no bookmarks
diff --git a/tests/test-debugcomplete.t b/tests/test-debugcomplete.t
--- a/tests/test-debugcomplete.t
+++ b/tests/test-debugcomplete.t
@@ -6,6 +6,7 @@
archive
backout
bisect
+ bookmarks
branch
branches
bundle
@@ -187,8 +188,8 @@
init: ssh, remotecmd
log: follow, follow-first, date, copies, keyword, rev, removed, only-merges, user, only-branch, branch, prune, patch, git, limit, no-merges, stat, style, template, include, exclude
merge: force, tool, rev, preview
- pull: update, force, rev, branch, ssh, remotecmd
- push: force, rev, branch, new-branch, ssh, remotecmd
+ pull: update, force, rev, branch, bookmark, ssh, remotecmd
+ push: force, rev, branch, bookmark, new-branch, ssh, remotecmd
remove: after, force, include, exclude
serve: accesslog, daemon, daemon-pipefds, errorlog, port, address, prefix, name, web-conf, webdir-conf, pid-file, stdio, templates, style, ipv6, certificate
status: all, modified, added, removed, deleted, clean, unknown, ignored, no-status, copies, print0, rev, change, include, exclude, subrepos
@@ -198,6 +199,7 @@
archive: no-decode, prefix, rev, type, subrepos, include, exclude
backout: merge, parent, tool, rev, include, exclude, message, logfile, date, user
bisect: reset, good, bad, skip, command, noupdate
+ bookmarks: force, rev, delete, rename
branch: force, clean
branches: active, closed
bundle: force, rev, branch, base, all, type, ssh, remotecmd
@@ -228,10 +230,10 @@
help:
identify: rev, num, id, branch, tags
import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
- incoming: force, newest-first, bundle, rev, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, subrepos
+ incoming: force, newest-first, bundle, rev, branch, bookmarks, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, subrepos
locate: rev, print0, fullpath, include, exclude
manifest: rev
- outgoing: force, rev, newest-first, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, subrepos
+ outgoing: force, rev, newest-first, branch, bookmarks, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, subrepos
parents: rev, style, template
paths:
recover:
diff --git a/tests/test-globalopts.t b/tests/test-globalopts.t
--- a/tests/test-globalopts.t
+++ b/tests/test-globalopts.t
@@ -284,6 +284,7 @@
archive create an unversioned archive of a repository revision
backout reverse effect of earlier changeset
bisect subdivision search of changesets
+ bookmarks track a line of development with movable markers
branch set or show the current branch name
branches list repository named branches
bundle create a changegroup file
@@ -360,6 +361,7 @@
archive create an unversioned archive of a repository revision
backout reverse effect of earlier changeset
bisect subdivision search of changesets
+ bookmarks track a line of development with movable markers
branch set or show the current branch name
branches list repository named branches
bundle create a changegroup file
diff --git a/tests/test-help.t b/tests/test-help.t
--- a/tests/test-help.t
+++ b/tests/test-help.t
@@ -55,6 +55,7 @@
archive create an unversioned archive of a repository revision
backout reverse effect of earlier changeset
bisect subdivision search of changesets
+ bookmarks track a line of development with movable markers
branch set or show the current branch name
branches list repository named branches
bundle create a changegroup file
@@ -127,6 +128,7 @@
archive create an unversioned archive of a repository revision
backout reverse effect of earlier changeset
bisect subdivision search of changesets
+ bookmarks track a line of development with movable markers
branch set or show the current branch name
branches list repository named branches
bundle create a changegroup file
@@ -649,6 +651,7 @@
archive create an unversioned archive of a repository revision
backout reverse effect of earlier changeset
bisect subdivision search of changesets
+ bookmarks track a line of development with movable markers
branch set or show the current branch name
branches list repository named branches
bundle create a changegroup file
diff --git a/tests/test-http-proxy.t b/tests/test-http-proxy.t
--- a/tests/test-http-proxy.t
+++ b/tests/test-http-proxy.t
@@ -104,13 +104,21 @@
* - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=heads HTTP/1.1" - - (glob)
* - - [*] "GET http://localhost:$HGPORT/?cmd=changegroup&roots=0000000000000000000000000000000000000000 HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=capabilities HTTP/1.1" - - (glob)
+ * - - [*] "GET http://localhost:$HGPORT/?cmd=listkeys&namespace=bookmarks HTTP/1.1" - - (glob)
diff --git a/tests/test-ssh.t b/tests/test-ssh.t
--- a/tests/test-ssh.t
+++ b/tests/test-ssh.t
@@ -41,9 +41,6 @@
> [server]
> uncompressed = True
>
- > [extensions]
- > bookmarks =
- >
> [hooks]
> changegroup = python ../printenv.py changegroup-in-remote 0 ../dummylog
> EOF
@@ -123,7 +120,6 @@
$ echo "[ui]" >> .hg/hgrc
$ echo "ssh = python ../dummyssh" >> .hg/hgrc
$ echo '[extensions]' >> .hg/hgrc
- $ echo 'bookmarks =' >> .hg/hgrc
find outgoing
@@ -197,7 +193,6 @@
$ cd ../local
$ echo '[extensions]' >> ../remote/.hg/hgrc
- $ echo 'bookmarks =' >> ../remote/.hg/hgrc
$ hg debugpushkey --config ui.ssh="python ../dummyssh" ssh://user@dummy/remote namespaces
bookmarks
namespaces
@@ -287,5 +282,3 @@
Got arguments 1:user at dummy 2:hg -R remote serve --stdio
Got arguments 1:user at dummy 2:hg -R remote serve --stdio
Got arguments 1:user at dummy 2:hg -R remote serve --stdio
- Got arguments 1:user at dummy 2:hg -R remote serve --stdio
- Got arguments 1:user at dummy 2:hg -R remote serve --stdio
More information about the Mercurial-devel
mailing list