# HG changeset patch # User Pierre-Yves David # Date 1536004764 -7200 # Node ID eb4d07a0b19feb0eac1ec8144d666cd135656c09 # Parent 9871809aa348d10bc2ba170830defac60f3e81f9# Parent d54a4b9c1d01a48325d14b743eb59f01a11eadd1 test-compat: merge stable into mercurial-4.6 diff -r 9871809aa348 -r eb4d07a0b19f .hgtags --- a/.hgtags Tue Aug 28 11:24:49 2018 +0200 +++ b/.hgtags Mon Sep 03 21:59:24 2018 +0200 @@ -69,3 +69,4 @@ 0887c30255a1a1808d74a63b16e896d457f8ef32 8.0.1 2c5d79c6459c6fabe0eb8723fc5041ac0dac7a9a 8.1.0 e7abf863e1130e14cd4d65e53467a199d267b4fd 8.1.1 +f1cde4c97806fc6d6cc4c1e09ea2f4081a3ebaec 8.1.2 diff -r 9871809aa348 -r eb4d07a0b19f CHANGELOG --- a/CHANGELOG Tue Aug 28 11:24:49 2018 +0200 +++ b/CHANGELOG Mon Sep 03 21:59:24 2018 +0200 @@ -4,7 +4,23 @@ 8.1.2 - in progress ------------------- + * prune: rename `--biject` flag to `--pair` (old flag is kept as an alias) + * pick: rename the "grab" command to "pick" to avoid ambiguity with graft + * discovery: enable obshashrange based discovery by default + +topic + + * revset: `topic("patterns")` now handle standard patterns ("re:", etc) + * revset: `topic(REVS)` matches revisions with same topic as REVS + * topic: using `s#` alias instead of `t#` and `b#` alias + (compat with old form is preserved) + +8.1.2 -- 2018-08-28 +------------------- + * obshashrange: improved robusness of the cache under heavy load + * obshashrange: force recomputation of the final obshash related cache + (to make sure people benefit from the 8.1.1 fixes) 8.1.1 -- 2018-08-21 ------------------- diff -r 9871809aa348 -r eb4d07a0b19f README --- a/README Tue Aug 28 11:24:49 2018 +0200 +++ b/README Mon Sep 03 21:59:24 2018 +0200 @@ -79,6 +79,22 @@ [extensions] evolve.serveronly = +Extension Purpose +================= + +The goal of this extension is to provide an appropriate place for code and +concept related to changeset evolution to mature. In this extension we allow +for hackier code, unlocking quick experimentation and faster iterations. + +In addition, the evolve extensions support a wider set of Mercurial version, +allowing us to reach a larger user base for feedback. The Evolve extension is +not tight to the Mercurial release cycle and can release new feature and bug +fix at a higher rate if necessary. + +Once a concept is ready enough, its implementation is moved into Mercurial +core. The maturation period helped us to get a clearer picture of what was +needed. During the upstreaming process, we can use this clearer picture to +clean up the code and upgrade it to an appropriate quality for Mercurial core. How to Contribute ================= @@ -125,3 +141,7 @@ In addition, we have compatibility branches to check tests on older version of Mercurial. They are the "mercurial-x.y" branches. They are used to apply expected test change only, no code change should happen there. + +test output change from a changeset in core should adds the following line to their description: + +CORE-TEST-OUTPUT-UPDATE: diff -r 9871809aa348 -r eb4d07a0b19f debian/changelog --- a/debian/changelog Tue Aug 28 11:24:49 2018 +0200 +++ b/debian/changelog Mon Sep 03 21:59:24 2018 +0200 @@ -1,4 +1,10 @@ -mercurial-evolve (8.1.1) unstable; urgency=medium +mercurial-evolve (8.1.2-1) unstable; urgency=medium + + * new upstream release + + -- Pierre-Yves David Tue, 28 Aug 2018 17:43:36 +0200 + +mercurial-evolve (8.1.1-1) unstable; urgency=medium * new upstream release diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/__init__.py --- a/hgext3rd/evolve/__init__.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/__init__.py Mon Sep 03 21:59:24 2018 +0200 @@ -1403,9 +1403,9 @@ cmdutil.unfinishedstates.append(data) afterresolved = ('evolvestate', _('hg evolve --continue')) - grabresolved = ('grabstate', _('hg grab --continue')) + pickresolved = ('pickstate', _('hg pick --continue')) cmdutil.afterresolvedstates.append(afterresolved) - cmdutil.afterresolvedstates.append(grabresolved) + cmdutil.afterresolvedstates.append(pickresolved) if util.safehasattr(cmdutil, 'STATES'): statedata = ('evolve', cmdutil.fileexistspredicate('evolvestate'), diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/cmdrewrite.py --- a/hgext3rd/evolve/cmdrewrite.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/cmdrewrite.py Mon Sep 03 21:59:24 2018 +0200 @@ -942,7 +942,9 @@ ('r', 'rev', [], _("revisions to prune")), ('k', 'keep', None, _("does not modify working copy during prune")), ('n', 'note', '', _('store a note on prune')), - ('', 'biject', False, _("do a 1-1 map between rev and successor ranges")), + ('', 'pair', False, _("record a pairing, such as a rebase or divergence resolution " + "(pairing multiple precursors to multiple successors)")), + ('', 'biject', False, _("alias to --pair (DEPRECATED)")), ('', 'fold', False, _("record a fold (multiple precursors, one successors)")), ('', 'split', False, @@ -972,7 +974,7 @@ single successor, you must pass the ``--fold`` option. If you want to supersede multiple revisions at the same time, use - ``--biject`` option to pair the pruned precursor and successor changesets. + ``--pair`` option to pair the pruned precursor and successor changesets. This is commonly useful for resolving history divergence, or when someone else does edits history without obsolescence enabled. """ @@ -981,11 +983,11 @@ succs = opts['new'] + opts['succ'] bookmarks = set(opts.get('bookmark')) metadata = _getmetadata(**opts) - biject = opts.get('biject') + biject = opts.get('pair') or opts.get('biject') fold = opts.get('fold') split = opts.get('split') - options = [o for o in ('biject', 'fold', 'split') if opts.get(o)] + options = [o for o in ('pair', 'fold', 'split') if opts.get(o)] if 1 < len(options): raise error.Abort(_("can only specify one of %s") % ', '.join(options)) @@ -1020,7 +1022,7 @@ sucs = tuple(repo[n] for n in sucs) if not biject and len(sucs) > 1 and len(precs) > 1: msg = "Can't use multiple successors for multiple precursors" - hint = _("use --biject to mark a series as a replacement" + hint = _("use --pair to mark a series as a replacement" " for another") raise error.Abort(msg, hint=hint) elif biject and len(sucs) != len(precs): @@ -1314,13 +1316,13 @@ lockmod.release(tr, lock, wlock) @eh.command( - 'grab', - [('r', 'rev', '', 'revision to grab'), - ('c', 'continue', False, 'continue interrupted grab'), - ('a', 'abort', False, 'abort interrupted grab'), + 'pick|grab', + [('r', 'rev', '', 'revision to pick'), + ('c', 'continue', False, 'continue interrupted pick'), + ('a', 'abort', False, 'abort interrupted pick'), ], _('[-r] rev')) -def grab(ui, repo, *revs, **opts): +def cmdpick(ui, repo, *revs, **opts): """grabs a commit, move it on the top of working directory parent and updates to it.""" @@ -1334,8 +1336,8 @@ if opts.get('rev'): revs.append(opts['rev']) - with repo.wlock(), repo.lock(), repo.transaction('grab'): - grabstate = state.cmdstate(repo, path='grabstate') + with repo.wlock(), repo.lock(), repo.transaction('pick'): + pickstate = state.cmdstate(repo, path='pickstate') pctx = repo['.'] if not cont and not abort: @@ -1349,28 +1351,28 @@ origctx = repo[revs.first()] if origctx in pctx.ancestors() or origctx.node() == pctx.node(): - raise error.Abort(_("cannot grab an ancestor revision")) + raise error.Abort(_("cannot pick an ancestor revision")) - rewriteutil.precheck(repo, [origctx.rev()], 'grab') + rewriteutil.precheck(repo, [origctx.rev()], 'pick') - ui.status(_('grabbing %d:%s "%s"\n') % + ui.status(_('picking %d:%s "%s"\n') % (origctx.rev(), origctx, origctx.description().split("\n", 1)[0])) stats = merge.graft(repo, origctx, origctx.p1(), ['local', 'destination']) if compat.hasconflict(stats): - grabstate.addopts({'orignode': origctx.node(), + pickstate.addopts({'orignode': origctx.node(), 'oldpctx': pctx.node()}) - grabstate.save() + pickstate.save() raise error.InterventionRequired(_("unresolved merge conflicts" " (see hg help resolve)")) elif abort: - if not grabstate: - raise error.Abort(_("no interrupted grab state exists")) - grabstate.load() - pctxnode = grabstate['oldpctx'] - ui.status(_("aborting grab, updating to %s\n") % + if not pickstate: + raise error.Abort(_("no interrupted pick state exists")) + pickstate.load() + pctxnode = pickstate['oldpctx'] + ui.status(_("aborting pick, updating to %s\n") % node.hex(pctxnode)[:12]) hg.updaterepo(repo, pctxnode, True) return 0 @@ -1379,26 +1381,26 @@ if revs: raise error.Abort(_("cannot specify both --continue and " "revision")) - if not grabstate: - raise error.Abort(_("no interrupted grab state exists")) + if not pickstate: + raise error.Abort(_("no interrupted pick state exists")) - grabstate.load() - orignode = grabstate['orignode'] + pickstate.load() + orignode = pickstate['orignode'] origctx = repo[orignode] overrides = {('phases', 'new-commit'): origctx.phase()} - with repo.ui.configoverride(overrides, 'grab'): + with repo.ui.configoverride(overrides, 'pick'): newnode = repo.commit(text=origctx.description(), user=origctx.user(), date=origctx.date(), extra=origctx.extra()) - if grabstate: - grabstate.delete() + if pickstate: + pickstate.delete() newctx = repo[newnode] if newnode else pctx - obsolete.createmarkers(repo, [(origctx, (newctx,))], operation="grab") + obsolete.createmarkers(repo, [(origctx, (newctx,))], operation="pick") if newnode is None: - ui.warn(_("note: grab of %d:%s created no changes to commit\n") % + ui.warn(_("note: picking %d:%s created no changes to commit\n") % (origctx.rev(), origctx)) return 0 diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/dagutil.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/evolve/dagutil.py Mon Sep 03 21:59:24 2018 +0200 @@ -0,0 +1,287 @@ +# dagutil.py - dag utilities for mercurial +# +# Copyright 2010 Benoit Boissinot +# and Peter Arrenbrecht +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. +# +# Imported from Mercurial code at cee9043c7dba + +from __future__ import absolute_import + +from mercurial.i18n import _ +from mercurial.node import nullrev + +class basedag(object): + '''generic interface for DAGs + + terms: + "ix" (short for index) identifies a nodes internally, + "id" identifies one externally. + + All params are ixs unless explicitly suffixed otherwise. + Pluralized params are lists or sets. + ''' + + def __init__(self): + self._inverse = None + + def nodeset(self): + '''set of all node ixs''' + raise NotImplementedError + + def heads(self): + '''list of head ixs''' + raise NotImplementedError + + def parents(self, ix): + '''list of parents ixs of ix''' + raise NotImplementedError + + def inverse(self): + '''inverse DAG, where parents becomes children, etc.''' + raise NotImplementedError + + def ancestorset(self, starts, stops=None): + ''' + set of all ancestors of starts (incl), but stop walk at stops (excl) + ''' + raise NotImplementedError + + def descendantset(self, starts, stops=None): + ''' + set of all descendants of starts (incl), but stop walk at stops (excl) + ''' + return self.inverse().ancestorset(starts, stops) + + def headsetofconnecteds(self, ixs): + ''' + subset of connected list of ixs so that no node has a descendant in it + + By "connected list" we mean that if an ancestor and a descendant are in + the list, then so is at least one path connecting them. + ''' + raise NotImplementedError + + def externalize(self, ix): + '''return a node id''' + return self._externalize(ix) + + def externalizeall(self, ixs): + '''return a list of (or set if given a set) of node ids''' + ids = self._externalizeall(ixs) + if isinstance(ixs, set): + return set(ids) + return list(ids) + + def internalize(self, id): + '''return a node ix''' + return self._internalize(id) + + def internalizeall(self, ids, filterunknown=False): + '''return a list of (or set if given a set) of node ixs''' + ixs = self._internalizeall(ids, filterunknown) + if isinstance(ids, set): + return set(ixs) + return list(ixs) + +class genericdag(basedag): + '''generic implementations for DAGs''' + + def ancestorset(self, starts, stops=None): + if stops: + stops = set(stops) + else: + stops = set() + seen = set() + pending = list(starts) + while pending: + n = pending.pop() + if n not in seen and n not in stops: + seen.add(n) + pending.extend(self.parents(n)) + return seen + + def headsetofconnecteds(self, ixs): + hds = set(ixs) + if not hds: + return hds + for n in ixs: + for p in self.parents(n): + hds.discard(p) + assert hds + return hds + +class revlogbaseddag(basedag): + '''generic dag interface to a revlog''' + + def __init__(self, revlog, nodeset): + basedag.__init__(self) + self._revlog = revlog + self._heads = None + self._nodeset = nodeset + + def nodeset(self): + return self._nodeset + + def heads(self): + if self._heads is None: + self._heads = self._getheads() + return self._heads + + def _externalize(self, ix): + return self._revlog.index[ix][7] + + def _externalizeall(self, ixs): + idx = self._revlog.index + return [idx[i][7] for i in ixs] + + def _internalize(self, id): + ix = self._revlog.rev(id) + if ix == nullrev: + raise LookupError(id, self._revlog.indexfile, _('nullid')) + return ix + + def _internalizeall(self, ids, filterunknown): + rl = self._revlog + if filterunknown: + return [r for r in map(rl.nodemap.get, ids) + if (r is not None + and r != nullrev + and r not in rl.filteredrevs)] + return [self._internalize(i) for i in ids] + +class revlogdag(revlogbaseddag): + '''dag interface to a revlog''' + + def __init__(self, revlog, localsubset=None): + revlogbaseddag.__init__(self, revlog, set(revlog)) + self._heads = localsubset + + def _getheads(self): + return [r for r in self._revlog.headrevs() if r != nullrev] + + def parents(self, ix): + rlog = self._revlog + idx = rlog.index + revdata = idx[ix] + prev = revdata[5] + if prev != nullrev: + prev2 = revdata[6] + if prev2 == nullrev: + return [prev] + return [prev, prev2] + prev2 = revdata[6] + if prev2 != nullrev: + return [prev2] + return [] + + def inverse(self): + if self._inverse is None: + self._inverse = inverserevlogdag(self) + return self._inverse + + def ancestorset(self, starts, stops=None): + rlog = self._revlog + idx = rlog.index + if stops: + stops = set(stops) + else: + stops = set() + seen = set() + pending = list(starts) + while pending: + rev = pending.pop() + if rev not in seen and rev not in stops: + seen.add(rev) + revdata = idx[rev] + for i in [5, 6]: + prev = revdata[i] + if prev != nullrev: + pending.append(prev) + return seen + + def headsetofconnecteds(self, ixs): + if not ixs: + return set() + rlog = self._revlog + idx = rlog.index + headrevs = set(ixs) + for rev in ixs: + revdata = idx[rev] + for i in [5, 6]: + prev = revdata[i] + if prev != nullrev: + headrevs.discard(prev) + assert headrevs + return headrevs + + def linearize(self, ixs): + '''linearize and topologically sort a list of revisions + + The linearization process tries to create long runs of revs where + a child rev comes immediately after its first parent. This is done by + visiting the heads of the given revs in inverse topological order, + and for each visited rev, visiting its second parent, then its first + parent, then adding the rev itself to the output list. + ''' + sorted = [] + visit = list(self.headsetofconnecteds(ixs)) + visit.sort(reverse=True) + finished = set() + + while visit: + cur = visit.pop() + if cur < 0: + cur = -cur - 1 + if cur not in finished: + sorted.append(cur) + finished.add(cur) + else: + visit.append(-cur - 1) + visit += [p for p in self.parents(cur) + if p in ixs and p not in finished] + assert len(sorted) == len(ixs) + return sorted + +class inverserevlogdag(revlogbaseddag, genericdag): + '''inverse of an existing revlog dag; see revlogdag.inverse()''' + + def __init__(self, orig): + revlogbaseddag.__init__(self, orig._revlog, orig._nodeset) + self._orig = orig + self._children = {} + self._roots = [] + self._walkfrom = len(self._revlog) - 1 + + def _walkto(self, walkto): + rev = self._walkfrom + cs = self._children + roots = self._roots + idx = self._revlog.index + while rev >= walkto: + data = idx[rev] + isroot = True + for prev in [data[5], data[6]]: # parent revs + if prev != nullrev: + cs.setdefault(prev, []).append(rev) + isroot = False + if isroot: + roots.append(rev) + rev -= 1 + self._walkfrom = rev + + def _getheads(self): + self._walkto(nullrev) + return self._roots + + def parents(self, ix): + if ix is None: + return [] + if ix <= self._walkfrom: + self._walkto(ix) + return self._children.get(ix, []) + + def inverse(self): + return self._orig diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/depthcache.py --- a/hgext3rd/evolve/depthcache.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/depthcache.py Mon Sep 03 21:59:24 2018 +0200 @@ -10,11 +10,9 @@ from __future__ import absolute_import import array -import weakref from mercurial import ( localrepo, - util, scmutil, ) @@ -85,30 +83,12 @@ self.depthcache.clear() super(depthcacherepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.depthcache.update(self) - self.depthcache.save(self) - super(depthcacherepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(depthcacherepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.depthcache.update(repo) - repo.depthcache.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-00depthcache', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.depthcache.update(self) + self.depthcache.save(self) + super(depthcacherepo, self).updatecaches(tr, **kwargs) repo.__class__ = depthcacherepo diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/evolvecmd.py --- a/hgext3rd/evolve/evolvecmd.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/evolvecmd.py Mon Sep 03 21:59:24 2018 +0200 @@ -230,7 +230,7 @@ # Checking for whether the phase-divergent changeset has common parents as # it's precursors. Phase-divergent changeset and precursor having different - # parents is a result of when the changeset is rebased, grabbed, histedit or + # parents is a result of when the changeset is rebased, picked, histedit or # evolved or any other operation which can change parent. In such cases, # when parents are not same, we first rebase the divergent changeset onto # parent or precursor and then perform later steps diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/exthelper.py --- a/hgext3rd/evolve/exthelper.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/exthelper.py Mon Sep 03 21:59:24 2018 +0200 @@ -11,12 +11,6 @@ util, ) -if util.safehasattr(registrar, 'command'): - command = registrar.command -else: # compat with hg < 4.3 - from mercurial import cmdutil - command = cmdutil.command - configitem = None dynamicdefault = None if util.safehasattr(registrar, 'configitem'): @@ -44,7 +38,7 @@ self._functionwrappers = [] self._duckpunchers = [] self.cmdtable = {} - self.command = command(self.cmdtable) + self.command = registrar.command(self.cmdtable) self.configtable = {} self._configitem = None diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/firstmergecache.py --- a/hgext3rd/evolve/firstmergecache.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/firstmergecache.py Mon Sep 03 21:59:24 2018 +0200 @@ -10,12 +10,10 @@ from __future__ import absolute_import import array -import weakref from mercurial import ( localrepo, node as nodemod, - util, ) from . import ( @@ -47,30 +45,12 @@ self.firstmergecache.clear() super(firstmergecacherepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.firstmergecache.update(self) - self.firstmergecache.save(self) - super(firstmergecacherepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(firstmergecacherepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.firstmergecache.update(repo) - repo.firstmergecache.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-01-firstparentcache', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.firstmergecache.update(self) + self.firstmergecache.save(self) + super(firstmergecacherepo, self).updatecaches(tr, **kwargs) repo.__class__ = firstmergecacherepo diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/hack/drophack.py --- a/hgext3rd/evolve/hack/drophack.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/hack/drophack.py Mon Sep 03 21:59:24 2018 +0200 @@ -21,12 +21,7 @@ cmdtable = {} -if util.safehasattr(registrar, 'command'): - command = registrar.command(cmdtable) -else: # compat with hg < 4.3 - from mercurial import cmdutil - command = cmdutil.command(cmdtable) - +command = registrar.command(cmdtable) @contextlib.contextmanager def timed(ui, caption): diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/legacy.py --- a/hgext3rd/evolve/legacy.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/legacy.py Mon Sep 03 21:59:24 2018 +0200 @@ -36,11 +36,7 @@ # compat with hg < 4.6 from mercurial.util import makedate -if util.safehasattr(registrar, 'command'): - commandfunc = registrar.command -else: # compat with hg < 4.3 - from mercurial import cmdutil - commandfunc = cmdutil.command +commandfunc = registrar.command ##################################################################### ### Older format management ### diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/metadata.py --- a/hgext3rd/evolve/metadata.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/metadata.py Mon Sep 03 21:59:24 2018 +0200 @@ -5,7 +5,7 @@ # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. -__version__ = '8.1.2.dev' +__version__ = '8.2.0.dev' testedwith = '4.3.2 4.4.2 4.5.2 4.6.2 4.7' minimumhgversion = '4.3' buglink = 'https://bz.mercurial-scm.org/' diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/obscache.py --- a/hgext3rd/evolve/obscache.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/obscache.py Mon Sep 03 21:59:24 2018 +0200 @@ -10,7 +10,6 @@ import errno import hashlib import struct -import weakref from mercurial import ( localrepo, @@ -478,31 +477,10 @@ self.obsstore.obscache.clear() super(obscacherepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - super(obscacherepo, self).updatecaches(tr, **kwargs) - self.obsstore.obscache.update(self) - self.obsstore.obscache.save(self) - - else: - def transaction(self, *args, **kwargs): - tr = super(obscacherepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - # As pointed in 'obscache.update', we could have the changelog - # and the obsstore in charge of updating the cache when new - # items goes it. The tranaction logic would then only be - # involved for the 'pending' and final writing on disk. - self.obsstore.obscache.update(repo) - self.obsstore.obscache.save(repo) - - tr.addpostclose('warmcache-obscache', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + super(obscacherepo, self).updatecaches(tr, **kwargs) + self.obsstore.obscache.update(self) + self.obsstore.obscache.save(self) repo.__class__ = obscacherepo diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/obsdiscovery.py --- a/hgext3rd/evolve/obsdiscovery.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/obsdiscovery.py Mon Sep 03 21:59:24 2018 +0200 @@ -29,7 +29,6 @@ import weakref from mercurial import ( - dagutil, error, exchange, extensions, @@ -60,6 +59,12 @@ wireprotov1server = wireprototypes from mercurial.wireproto import wirepeer, encodelist, decodelist +try: + from mercurial import dagutil + dagutil.revlogdag +except (ImportError, AttributeError): # <= hg-4.7 + from . import dagutil + _pack = struct.pack _unpack = struct.unpack _calcsize = struct.calcsize @@ -394,7 +399,7 @@ class _obshashcache(obscache.dualsourcecache): - _schemaversion = 2 + _schemaversion = 3 _cachename = 'evo-ext-obshashrange' # used for error message _filename = 'cache/evoext_obshashrange_v2.sqlite' @@ -662,30 +667,12 @@ self.obsstore.rangeobshashcache.clear() super(obshashrepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.obsstore.rangeobshashcache.update(self) - self.obsstore.rangeobshashcache.save(self) - super(obshashrepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(obshashrepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.obsstore.rangeobshashcache.update(repo) - repo.obsstore.rangeobshashcache.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-20obshashrange', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.obsstore.rangeobshashcache.update(self) + self.obsstore.rangeobshashcache.save(self) + super(obshashrepo, self).updatecaches(tr, **kwargs) repo.__class__ = obshashrepo @@ -750,7 +737,7 @@ return encodelist(hashes) def _useobshashrange(repo): - base = repo.ui.configbool('experimental', 'obshashrange', False) + base = repo.ui.configbool('experimental', 'obshashrange', True) if base: maxrevs = repo.ui.configint('experimental', 'obshashrange.max-revs', None) if maxrevs is not None and maxrevs < len(repo.unfiltered()): diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/stablerangecache.py --- a/hgext3rd/evolve/stablerangecache.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/stablerangecache.py Mon Sep 03 21:59:24 2018 +0200 @@ -12,7 +12,6 @@ import random import sqlite3 import time -import weakref from mercurial import ( error, @@ -32,6 +31,33 @@ eh = exthelper.exthelper() +LONG_WARNING_TIME = 60 + +LONG_MESSAGE = """Stable range cache is taking a while to load + +Your repository is probably big. + +Stable range are used for discovery missing osbsolescence markers during +exchange. While the algorithm we use can scale well for large repositories, the +naive python implementation that you are using is not very efficient, the +storage backend for that cache neither. + +This computation will finish in a finite amount of time, even for repositories +with millions of revision and many merges. However It might take multiple tens +of minutes to complete in such case. + +In the future, better implementation of the algorithm in a more appropriate +language than Python will make it much faster. This data should also get +exchanged between server and clients removing recomputation needs. + +In the mean time, got take a break while this cache is warming. + +See `hg help -e evolve` for details about how to control obsmarkers discovery and +the update of related cache. + +--- Sorry for the delay --- +""" + class stablerangeondiskbase(stablerange.stablerangecached, genericcaches.changelogsourcebase): """combine the generic stablerange cache usage with generic changelog one @@ -57,7 +83,8 @@ # progress report is showing up in the profile for small and fast # repository so we only update it every so often progress_each = 100 - progress_last = time.time() + initial_time = progress_last = time.time() + warned_long = False heapify(rangeheap) while rangeheap: rangeid = heappop(rangeheap) @@ -65,6 +92,8 @@ if not seen % progress_each: # if a lot of time passed, report more often progress_new = time.time() + if not warned_long and LONG_WARNING_TIME < (progress_new - initial_time): + repo.ui.warn(LONG_MESSAGE) if (1 < progress_each) and (0.1 < progress_new - progress_last): progress_each /= 10 ui.progress(_("filling stablerange cache"), seen, @@ -403,30 +432,12 @@ del self.stablerange super(stablerangerepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.stablerange.update(self) - self.stablerange.save(self) - super(stablerangerepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(stablerangerepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.stablerange.update(repo) - repo.stablerange.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-10stablerange', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.stablerange.update(self) + self.stablerange.save(self) + super(stablerangerepo, self).updatecaches(tr, **kwargs) repo.__class__ = stablerangerepo diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/stablesort.py --- a/hgext3rd/evolve/stablesort.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/stablesort.py Mon Sep 03 21:59:24 2018 +0200 @@ -10,7 +10,6 @@ import array import collections import struct -import weakref from mercurial import ( commands, @@ -18,7 +17,6 @@ error, node as nodemod, scmutil, - util, ) from mercurial.i18n import _ @@ -669,30 +667,12 @@ self.stablesort.clear() super(stablesortrepo, self).destroyed() - if util.safehasattr(repo, 'updatecaches'): - @localrepo.unfilteredmethod - def updatecaches(self, tr=None, **kwargs): - if utility.shouldwarmcache(self, tr): - self.stablesort.update(self) - self.stablesort.save(self) - super(stablesortrepo, self).updatecaches(tr, **kwargs) - - else: - def transaction(self, *args, **kwargs): - tr = super(stablesortrepo, self).transaction(*args, **kwargs) - reporef = weakref.ref(self) - - def _warmcache(tr): - repo = reporef() - if repo is None: - return - repo = repo.unfiltered() - repo.stablesort.update(repo) - repo.stablesort.save(repo) - - if utility.shouldwarmcache(self, tr): - tr.addpostclose('warmcache-02stablesort', _warmcache) - return tr + @localrepo.unfilteredmethod + def updatecaches(self, tr=None, **kwargs): + if utility.shouldwarmcache(self, tr): + self.stablesort.update(self) + self.stablesort.save(self) + super(stablesortrepo, self).updatecaches(tr, **kwargs) repo.__class__ = stablesortrepo diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/state.py --- a/hgext3rd/evolve/state.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/state.py Mon Sep 03 21:59:24 2018 +0200 @@ -28,7 +28,7 @@ from mercurial.i18n import _ class cmdstate(): - """a wrapper class to store the state of commands like `evolve`, `grab` + """a wrapper class to store the state of commands like `evolve`, `pick` All the data for the state is stored in the form of key-value pairs in a dictionary. diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/templatekw.py --- a/hgext3rd/evolve/templatekw.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/templatekw.py Mon Sep 03 21:59:24 2018 +0200 @@ -24,17 +24,6 @@ eh = exthelper.exthelper() ### template keywords -# XXX it does not handle troubles well :-/ - -if not util.safehasattr(templatekw, 'showobsolete'): - # hg < 4.2 - @eh.templatekw('obsolete') - def obsoletekw(repo, ctx, templ, **args): - """String. Whether the changeset is ``obsolete``. - """ - if ctx.obsolete(): - return 'obsolete' - return '' if util.safehasattr(templatekw, 'compatlist'): @eh.templatekw('troubles', requires=set(['ctx', 'templ'])) diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/evolve/utility.py --- a/hgext3rd/evolve/utility.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/evolve/utility.py Mon Sep 03 21:59:24 2018 +0200 @@ -64,7 +64,7 @@ # note: we should not get to the default case warm = configbool('experimental', 'obshashrange.warm-cache', True) - if not configbool('experimental', 'obshashrange', False): + if not configbool('experimental', 'obshashrange', True): return False if not warm: return False diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/topic/__init__.py Mon Sep 03 21:59:24 2018 +0200 @@ -29,8 +29,10 @@ your current topic. Topic is offering you aliases reference to changeset in your current topic -stack as 't#'. For example, 't1' refers to the root of your stack, 't2' to the -second commits, etc. The 'hg stack' command show these number. +stack as 's#'. For example, 's1' refers to the root of your stack, 's2' to the +second commits, etc. The 'hg stack' command show these number. 's0' can be used +to refer to the parent of the topic root. Updating using `hg up s0` will keep +the topic active. Push behavior will change a bit with topic. When pushing to a publishing repository the changesets will turn public and the topic data on them will fade @@ -132,7 +134,6 @@ registrar, scmutil, templatefilters, - templatekw, util, ) @@ -149,13 +150,8 @@ topicmap, ) -if util.safehasattr(registrar, 'command'): - commandfunc = registrar.command -else: # compat with hg < 4.3 - commandfunc = cmdutil.command - cmdtable = {} -command = commandfunc(cmdtable) +command = registrar.command(cmdtable) colortable = {'topic.active': 'green', 'topic.list.troubledcount': 'red', 'topic.list.headcount.multiple': 'yellow', @@ -181,7 +177,7 @@ 'topic.active': 'green', } -__version__ = '0.10.1.dev' +__version__ = '0.11.0.dev' testedwith = '4.3.3 4.4.2 4.5.2 4.6.2 4.7' minimumhgversion = '4.3' @@ -231,6 +227,8 @@ default=None, ) +templatekeyword = registrar.templatekeyword() + def _contexttopic(self, force=False): if not (force or self.mutable()): return '' @@ -240,8 +238,8 @@ def _contexttopicidx(self): topic = self.topic() if not topic: - # XXX we might want to include t0 here, - # however t0 is related to 'currenttopic' which has no place here. + # XXX we might want to include s0 here, + # however s0 is related to 'currenttopic' which has no place here. return None revlist = stack.stack(self._repo, topic=topic) try: @@ -257,12 +255,23 @@ return None context.basectx.topicidx = _contexttopicidx +stackrev = re.compile(r'^s\d+$') topicrev = re.compile(r'^t\d+$') branchrev = re.compile(r'^b\d+$') def _namemap(repo, name): revs = None - if topicrev.match(name): + if stackrev.match(name): + idx = int(name[1:]) + tname = topic = repo.currenttopic + if topic: + ttype = 'topic' + revs = list(stack.stack(repo, topic=topic)) + else: + ttype = 'branch' + tname = branch = repo[None].branch() + revs = list(stack.stack(repo, branch=branch)) + elif topicrev.match(name): idx = int(name[1:]) ttype = 'topic' tname = topic = repo.currenttopic @@ -279,9 +288,12 @@ try: r = revs[idx] except IndexError: - msg = _('cannot resolve "%s": %s "%s" has only %d changesets') + if ttype == 'topic': + msg = _('cannot resolve "%s": %s "%s" has only %d changesets') + elif ttype == 'branch': + msg = _('cannot resolve "%s": %s "%s" has only %d non-public changesets') raise error.Abort(msg % (name, ttype, tname, len(revs) - 1)) - # b0 or t0 can be None + # b0 or t0 or s0 can be None if r == -1 and idx == 0: msg = _('the %s "%s" has no %s') raise error.Abort(msg % (ttype, tname, name)) @@ -323,7 +335,7 @@ extensions.wrapfunction(cmdutil, 'buildcommittext', committextwrap) extensions.wrapfunction(merge, 'update', mergeupdatewrap) - # We need to check whether t0 or b0 is passed to override the default update + # We need to check whether t0 or b0 or s0 is passed to override the default update # behaviour of changing topic and I can't find a better way # to do that as scmutil.revsingle returns the rev number and hence we can't # plug into logic for this into mergemod.update(). @@ -338,7 +350,6 @@ cmdutil.summaryhooks.add('topic', summaryhook) - templatekw.keywords['topic'] = topickw # Wrap workingctx extra to return the topic name extensions.wrapfunction(context.workingctx, '__init__', wrapinit) # Wrap changelog.add to drop empty topic @@ -510,9 +521,11 @@ 'topics', 'topic', namemap=_namemap, nodemap=_nodemap, listnames=lambda repo: repo.topics)) -def topickw(**args): +@templatekeyword('topic', requires={'ctx'}) +def topickw(context, mapping): """:topic: String. The topic of the changeset""" - return args['ctx'].topic() + ctx = context.resource(mapping, 'ctx') + return ctx.topic() def wrapinit(orig, self, repo, *args, **kwargs): orig(self, repo, *args, **kwargs) @@ -647,9 +660,9 @@ ct = repo.currenttopic if clear: - empty = stack.stack(repo, topic=ct).changesetcount == 0 - if empty: - if ct: + if ct: + empty = stack.stack(repo, topic=ct).changesetcount == 0 + if empty: ui.status(_('clearing empty topic "%s"\n') % ct) return _changecurrenttopic(repo, None) @@ -1152,7 +1165,6 @@ # rebased commit. We have explicitly stored in config if rebase is # running. ot = repo.currenttopic - empty = stack.stack(repo, topic=ot).changesetcount == 0 if repo.ui.hasconfig('experimental', 'topicrebase'): isrebase = True if repo.ui.configbool('_internal', 'keep-topic'): @@ -1166,8 +1178,10 @@ f.write(t) if t and t != ot: repo.ui.status(_("switching to topic %s\n") % t) - if ot and not t and empty: - repo.ui.status(_('clearing empty topic "%s"\n') % ot) + if ot and not t: + empty = stack.stack(repo, topic=ot).changesetcount == 0 + if empty: + repo.ui.status(_('clearing empty topic "%s"\n') % ot) elif ist0: repo.ui.status(_("preserving the current topic '%s'\n") % ot) return ret @@ -1176,7 +1190,7 @@ def checkt0(orig, ui, repo, node=None, rev=None, *args, **kwargs): - thezeros = set(['t0', 'b0']) + thezeros = set(['t0', 'b0', 's0']) backup = repo.ui.backupconfig('_internal', 'keep-topic') try: if node in thezeros or rev in thezeros: diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/topic/destination.py --- a/hgext3rd/topic/destination.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/topic/destination.py Mon Sep 03 21:59:24 2018 +0200 @@ -59,7 +59,10 @@ """decide on an update destination from current topic""" movemark = node = None topic = repo.currenttopic - revs = repo.revs('.::topic("%s")' % topic) + if topic: + revs = repo.revs('.::topic(%s)', topic) + else: + revs = [] if not revs: return None, None, None node = revs.last() diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/topic/revset.py --- a/hgext3rd/topic/revset.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/topic/revset.py Mon Sep 03 21:59:24 2018 +0200 @@ -1,13 +1,13 @@ from __future__ import absolute_import from mercurial import ( + error, registrar, revset, util, ) from . import ( - constants, destination, stack, ) @@ -23,36 +23,64 @@ revsetpredicate = registrar.revsetpredicate() -@revsetpredicate('topic([topic])') -def topicset(repo, subset, x): - """Specified topic or all changes with any topic specified. +def getstringstrict(x, err): + if x and (x[0] == 'string'): + return x[1] + raise error.ParseError(err) - If `topic` starts with `re:` the remainder of the name is treated +@revsetpredicate('topic([string or set])') +def topicset(repo, subset, x): + """All changesets with the specified topic or the topics of the given + changesets. Without the argument, all changesets with any topic specified. + + If `string` starts with `re:` the remainder of the name is treated as a regular expression. - - TODO: make `topic(revset)` work the same as `branch(revset)`. """ args = revset.getargs(x, 0, 1, 'topic takes one or no arguments') - if args: - # match a specific topic - topic = revset.getstring(args[0], 'topic() argument must be a string') - if topic == '.': - topic = repo['.'].extra().get('topic', '') - _kind, _pattern, matcher = mkmatcher(topic) - else: - matcher = lambda t: bool(t) mutable = revset._notpublic(repo, revset.fullreposet(repo), ()) - rawchange = repo.changelog.changelogrevision - key = constants.extrakey + if not args: + return (subset & mutable).filter(lambda r: bool(repo[r].topic())) + + try: + topic = getstringstrict(args[0], '') + except error.ParseError: + # not a string, but another revset + pass + else: + kind, pattern, matcher = mkmatcher(topic) + + def matches(r): + topic = repo[r].topic() + if not topic: + return False + return matcher(topic) + + if kind == 'literal': + # note: falls through to the revset case if no topic with this name + # exists and pattern kind is not specified explicitly - def matchtopic(r): - topic = rawchange(r).extra.get(key) - if topic is None: + if pattern not in repo.topics and topic.startswith('literal:'): + raise error.RepoLookupError("topic '%s' does not exist" + % pattern) + return (subset & mutable).filter(matches) + else: + return (subset & mutable).filter(matches) + + s = revset.getset(repo, revset.fullreposet(repo), x) + topics = set(repo[r].topic() for r in s) + topics.discard('') + + def matches(r): + if r in s: + return True + topic = repo[r].topic() + if not topic: return False - return matcher(topic) - return (subset & mutable).filter(matchtopic) + return topic in topics + + return (subset & mutable).filter(matches) @revsetpredicate('ngtip([branch])') def ngtipset(repo, subset, x): diff -r 9871809aa348 -r eb4d07a0b19f hgext3rd/topic/stack.py --- a/hgext3rd/topic/stack.py Tue Aug 28 11:24:49 2018 +0200 +++ b/hgext3rd/topic/stack.py Mon Sep 03 21:59:24 2018 +0200 @@ -239,11 +239,11 @@ msg %= (branch, topic) raise error.ProgrammingError(msg) elif topic is not None: - prefix = 't' + prefix = 's' if topic not in repo.topics: raise error.Abort(_('cannot resolve "%s": no such topic found') % topic) elif branch is not None: - prefix = 'b' + prefix = 's' else: raise error.ProgrammingError('neither branch and topic specified (not defined yet)') diff -r 9871809aa348 -r eb4d07a0b19f tests/test-discovery-obshashrange.t --- a/tests/test-discovery-obshashrange.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-discovery-obshashrange.t Mon Sep 03 21:59:24 2018 +0200 @@ -1118,3 +1118,31 @@ 5 c8d03c1b5e94 5 1 6 446c2dc3bce5 6 f69452c5b1af 6 1 7 000000000000 +Cache warming capabilities +-------------------------- + + $ hg config experimental.obshashrange + 1 + $ hg config experimental.obshashrange.warm-cache + [1] + $ hg debugupdatecache + $ ls -1 .hg/cache/evoext* + .hg/cache/evoext-depthcache-00 + .hg/cache/evoext-firstmerge-00 + .hg/cache/evoext-obscache-00 + .hg/cache/evoext-stablesortcache-00 + .hg/cache/evoext_obshashrange_v2.sqlite + .hg/cache/evoext_stablerange_v2.sqlite + $ rm -f .hg/cache/evoext* + $ ls -1 .hg/cache/ | grep evoext + [1] + $ hg debugupdatecache --debug + updating the branch cache + invalid branchheads cache (served): tip differs + $ f -s .hg/cache/evoext* + .hg/cache/evoext-depthcache-00: size=96 + .hg/cache/evoext-firstmerge-00: size=96 + .hg/cache/evoext-obscache-00: size=73 + .hg/cache/evoext-stablesortcache-00: size=100 + .hg/cache/evoext_obshashrange_v2.sqlite: size=??* (glob) + .hg/cache/evoext_stablerange_v2.sqlite: size=??* (glob) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-evolve-abort-phasediv.t --- a/tests/test-evolve-abort-phasediv.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-evolve-abort-phasediv.t Mon Sep 03 21:59:24 2018 +0200 @@ -43,8 +43,8 @@ $ hg up .^^^ 0 files updated, 0 files merged, 3 files removed, 0 files unresolved - $ hg grab -r .~-3 - grabbing 4:c41c793e0ef1 "added d" + $ hg pick -r .~-3 + picking 4:c41c793e0ef1 "added d" $ echo foobar > c $ hg add c $ hg amend @@ -151,8 +151,8 @@ $ hg prev 0 files updated, 0 files merged, 2 files removed, 0 files unresolved [1] added a - $ hg grab -r ca1b80f - grabbing 3:ca1b80f7960a "added c" + $ hg pick -r ca1b80f + picking 3:ca1b80f7960a "added c" $ echo foobar > b $ hg add b $ hg amend diff -r 9871809aa348 -r eb4d07a0b19f tests/test-evolve-issue5832.t --- a/tests/test-evolve-issue5832.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-evolve-issue5832.t Mon Sep 03 21:59:24 2018 +0200 @@ -191,8 +191,8 @@ 0 files updated, 0 files merged, 4 files removed, 0 files unresolved $ echo l > l $ hg ci -Aqm "added l" - $ hg grab -r 1b24879c5c3c - grabbing 1:1b24879c5c3c "added a" + $ hg pick -r 1b24879c5c3c + picking 1:1b24879c5c3c "added a" 2 new orphan changesets $ hg up bde1d2b6b5e5 @@ -337,8 +337,8 @@ 0 files updated, 0 files merged, 4 files removed, 0 files unresolved $ echo l > l $ hg ci -Aqm "added l" - $ hg grab -r 1b24879c5c3c - grabbing 1:1b24879c5c3c "added a" + $ hg pick -r 1b24879c5c3c + picking 1:1b24879c5c3c "added a" 2 new orphan changesets $ hg up bde1d2b6b5e5 diff -r 9871809aa348 -r eb4d07a0b19f tests/test-evolve-serveronly-bundle2.t --- a/tests/test-evolve-serveronly-bundle2.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-evolve-serveronly-bundle2.t Mon Sep 03 21:59:24 2018 +0200 @@ -86,9 +86,9 @@ =================== $ curl -s http://localhost:$HGPORT/?cmd=hello - capabilities: _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 batch * (glob) + capabilities: _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 _evoext_obshashrange_v1 batch * (glob) $ curl -s http://localhost:$HGPORT/?cmd=capabilities - _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 batch * (no-eol) (glob) + _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 _evoext_obshashrange_v1 batch * (no-eol) (glob) $ curl -s "http://localhost:$HGPORT/?cmd=listkeys&namespace=namespaces" | sort bookmarks @@ -151,9 +151,9 @@ obsolete phases $ curl -s http://localhost:$HGPORT/?cmd=hello - capabilities: _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 batch * (glob) + capabilities: _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 _evoext_obshashrange_v1 batch * (glob) $ curl -s http://localhost:$HGPORT/?cmd=capabilities - _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 batch * (no-eol) (glob) + _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 _evoext_obshashrange_v1 batch * (no-eol) (glob) $ echo '[experimental]' >> server/.hg/hgrc $ echo 'evolution=!' >> server/.hg/hgrc @@ -178,9 +178,9 @@ phases $ curl -s http://localhost:$HGPORT/?cmd=hello - capabilities: _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 batch * (glob) + capabilities: _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 _evoext_obshashrange_v1 batch * (glob) $ curl -s http://localhost:$HGPORT/?cmd=capabilities - _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 batch * (no-eol) (glob) + _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 _evoext_obshashrange_v1 batch * (no-eol) (glob) Test obshashrange discover =========================================== diff -r 9871809aa348 -r eb4d07a0b19f tests/test-evolve-stop-phasediv.t --- a/tests/test-evolve-stop-phasediv.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-evolve-stop-phasediv.t Mon Sep 03 21:59:24 2018 +0200 @@ -40,8 +40,8 @@ $ hg up .^^^ 0 files updated, 0 files merged, 3 files removed, 0 files unresolved - $ hg grab -r .~-3 - grabbing 4:c41c793e0ef1 "added d" + $ hg pick -r .~-3 + picking 4:c41c793e0ef1 "added d" $ echo foobar > c $ hg add c $ hg amend diff -r 9871809aa348 -r eb4d07a0b19f tests/test-evolve-topic.t --- a/tests/test-evolve-topic.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-evolve-topic.t Mon Sep 03 21:59:24 2018 +0200 @@ -80,11 +80,11 @@ ### topic: foo (?) ### branch: default (?) ### target: default (branch) - t4@ add fff (current) - t3: add eee - t2: add ddd - t1: add ccc - t0^ add bbb (base) + s4@ add fff (current) + s3: add eee + s2: add ddd + s1: add ccc + s0^ add bbb (base) $ hg up 'desc(ddd)' 0 files updated, 0 files merged, 2 files removed, 0 files unresolved $ echo ddd >> ddd @@ -260,12 +260,12 @@ $ hg stack ### topic: bar ### target: default (branch) - t5$ add jjj (unstable) - t4$ add iii (unstable) - t3$ add hhh (unstable) - t2$ add ggg (current unstable) - t1: add fff - t0^ add eee (base) + s5$ add jjj (unstable) + s4$ add iii (unstable) + s3$ add hhh (unstable) + s2$ add ggg (current unstable) + s1: add fff + s0^ add eee (base) $ hg prev 0 files updated, 0 files merged, 1 files removed, 0 files unresolved diff -r 9871809aa348 -r eb4d07a0b19f tests/test-evolve.t --- a/tests/test-evolve.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-evolve.t Mon Sep 03 21:59:24 2018 +0200 @@ -596,8 +596,8 @@ |/ o 0:8685c6d34325@default(draft) add 0 - $ hg grab -r3 - grabbing 3:0e84df4912da "add 3" + $ hg pick -r3 + picking 3:0e84df4912da "add 3" $ hg graft -r1 grafting 1:73d38bb17fd7 "add 1" $ hg prune -r2 --succ . @@ -618,7 +618,7 @@ o 0:8685c6d34325@default(draft) add 0 $ hg debugobsolete - 0e84df4912da4c7cad22a3b4fcfd58ddfb7c8ae9 fa455b5098e0ce8c1871edf6369f32be7d8b4d1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'grab', 'user': 'test'} + 0e84df4912da4c7cad22a3b4fcfd58ddfb7c8ae9 fa455b5098e0ce8c1871edf6369f32be7d8b4d1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'pick', 'user': 'test'} db038628b9e56f51a454c0da0c508df247b41748 417185465d2c68e575cff4cd6ed8a4047505ef24 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'prune', 'user': 'test'} Test grab --continue @@ -628,8 +628,8 @@ $ hg ci -Am conflict 1 created new head $ hg up -qC 6 - $ hg grab -r 7 - grabbing 7:a5bfd90a2f29 "conflict" + $ hg pick -r 7 + picking 7:a5bfd90a2f29 "conflict" merging 1 warning: conflicts while merging 1! (edit, then use 'hg resolve --mark') unresolved merge conflicts (see hg help resolve) @@ -639,8 +639,8 @@ $ echo 3 > 1 $ hg resolve -m 1 (no more unresolved files) - continue: hg grab --continue - $ hg grab --continue + continue: hg pick --continue + $ hg pick --continue $ glog --hidden @ 8:fb2c0f0a0c54@default(draft) conflict | @@ -661,9 +661,9 @@ o 0:8685c6d34325@default(draft) add 0 $ hg debugobsolete - 0e84df4912da4c7cad22a3b4fcfd58ddfb7c8ae9 fa455b5098e0ce8c1871edf6369f32be7d8b4d1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'grab', 'user': 'test'} + 0e84df4912da4c7cad22a3b4fcfd58ddfb7c8ae9 fa455b5098e0ce8c1871edf6369f32be7d8b4d1c 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '4', 'operation': 'pick', 'user': 'test'} db038628b9e56f51a454c0da0c508df247b41748 417185465d2c68e575cff4cd6ed8a4047505ef24 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'prune', 'user': 'test'} - a5bfd90a2f29c7ccb8f917ff4e5013a9053d0a04 fb2c0f0a0c54be4367988521bad2cbd33a540969 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'grab', 'user': 'test'} + a5bfd90a2f29c7ccb8f917ff4e5013a9053d0a04 fb2c0f0a0c54be4367988521bad2cbd33a540969 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '12', 'operation': 'pick', 'user': 'test'} Test touch diff -r 9871809aa348 -r eb4d07a0b19f tests/test-grab.t --- a/tests/test-grab.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-grab.t Mon Sep 03 21:59:24 2018 +0200 @@ -16,16 +16,18 @@ $ hg init repo $ cd repo $ hg help grab - hg grab [-r] rev + hg pick [-r] rev + + aliases: grab grabs a commit, move it on the top of working directory parent and updates to it. options: - -r --rev VALUE revision to grab - -c --continue continue interrupted grab - -a --abort abort interrupted grab + -r --rev VALUE revision to pick + -c --continue continue interrupted pick + -a --abort abort interrupted pick (some details hidden, use --verbose to show complete help) @@ -43,45 +45,45 @@ Grabbing an ancestor - $ hg grab -r 7c3bad9141dc - abort: cannot grab an ancestor revision + $ hg pick -r 7c3bad9141dc + abort: cannot pick an ancestor revision [255] Grabbing the working directory parent - $ hg grab -r . - abort: cannot grab an ancestor revision + $ hg pick -r . + abort: cannot pick an ancestor revision [255] Specifying multiple revisions to grab - $ hg grab 1f0dee641bb7 -r 7c3bad9141dc + $ hg pick 1f0dee641bb7 -r 7c3bad9141dc abort: specify just one revision [255] Specifying no revisions to grab - $ hg grab + $ hg pick abort: empty revision set [255] Continuing without interrupted grab - $ hg grab --continue - abort: no interrupted grab state exists + $ hg pick --continue + abort: no interrupted pick state exists [255] Aborting without interrupted grab - $ hg grab --abort - abort: no interrupted grab state exists + $ hg pick --abort + abort: no interrupted pick state exists [255] Specifying both continue and revs $ hg up 1f0dee641bb7 0 files updated, 0 files merged, 2 files removed, 0 files unresolved - $ hg grab -r 4538525df7e2 --continue + $ hg pick -r 4538525df7e2 --continue abort: cannot specify both --continue and revision [255] @@ -104,8 +106,8 @@ Grabbing a revision - $ hg grab 7c3bad9141dc - grabbing 1:7c3bad9141dc "add b" + $ hg pick 7c3bad9141dc + picking 1:7c3bad9141dc "add b" 1 new orphan changesets $ hg glog @ 5:7c15c05db6fa add b @@ -141,9 +143,9 @@ |/ o 0:1f0dee641bb7 add a - $ hg grab -r 4538525df7e2 - grabbing 2:4538525df7e2 "add c" - note: grab of 2:4538525df7e2 created no changes to commit + $ hg pick -r 4538525df7e2 + picking 2:4538525df7e2 "add c" + note: picking 2:4538525df7e2 created no changes to commit $ hg glog @ 6:c4636a81ebeb add c @@ -162,8 +164,8 @@ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved $ echo foo > c $ hg ci -Aqm "foo to c" - $ hg grab -r c4636a81ebeb - grabbing 6:c4636a81ebeb "add c" + $ hg pick -r c4636a81ebeb + picking 6:c4636a81ebeb "add c" merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') unresolved merge conflicts (see hg help resolve) @@ -172,8 +174,8 @@ $ echo foobar > c $ hg resolve --all --mark (no more unresolved files) - continue: hg grab --continue - $ hg grab --continue + continue: hg pick --continue + $ hg pick --continue $ hg glog @ 8:44e155eb95c7 add c | @@ -200,8 +202,8 @@ $ hg up 44e155eb95c7 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg grab 4e04628911f6 - grabbing 9:4e04628911f6 "foo to c" + $ hg pick 4e04628911f6 + picking 9:4e04628911f6 "foo to c" merging c warning: conflicts while merging c! (edit, then use 'hg resolve --mark') unresolved merge conflicts (see hg help resolve) @@ -209,12 +211,12 @@ $ echo foobar > c $ hg resolve -m (no more unresolved files) - continue: hg grab --continue + continue: hg pick --continue - $ hg grab --continue - note: grab of 9:4e04628911f6 created no changes to commit + $ hg pick --continue + note: picking 9:4e04628911f6 created no changes to commit -Testing the abort functionality of hg grab +Testing the abort functionality of hg pick $ echo foo > b $ hg ci -Aqm "foo to b" @@ -225,15 +227,15 @@ | ~ - $ hg grab -r 7c15c05db6fa - grabbing 5:7c15c05db6fa "add b" + $ hg pick -r 7c15c05db6fa + picking 5:7c15c05db6fa "add b" merging b warning: conflicts while merging b! (edit, then use 'hg resolve --mark') unresolved merge conflicts (see hg help resolve) [1] - $ hg grab --abort - aborting grab, updating to c437988de89f + $ hg pick --abort + aborting pick, updating to c437988de89f $ hg glog @ 10:c437988de89f foo to b @@ -255,8 +257,8 @@ $ hg phase -r 7c15c05db6fa -p - $ hg grab -r 7c15c05db6fa - abort: cannot grab public changesets: 7c15c05db6fa + $ hg pick -r 7c15c05db6fa + abort: cannot pick public changesets: 7c15c05db6fa (see 'hg help phases' for details) [255] @@ -281,8 +283,8 @@ $ hg phase -r 7c15c05db6fa -s -f - $ hg grab -r 7c15c05db6fa - grabbing 5:7c15c05db6fa "add b" + $ hg pick -r 7c15c05db6fa + picking 5:7c15c05db6fa "add b" merging b warning: conflicts while merging b! (edit, then use 'hg resolve --mark') unresolved merge conflicts (see hg help resolve) @@ -291,9 +293,9 @@ $ echo bar > b $ hg resolve -m (no more unresolved files) - continue: hg grab --continue + continue: hg pick --continue - $ hg grab --continue + $ hg pick --continue $ hg phase -r . 11: secret @@ -328,8 +330,8 @@ $ hg up 10427de9e26e 3 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ hg grab -r 508d572e7053 - grabbing 12:508d572e7053 "added l" + $ hg pick -r 508d572e7053 + picking 12:508d572e7053 "added l" $ hg phase -r . 13: secret diff -r 9871809aa348 -r eb4d07a0b19f tests/test-options.t diff -r 9871809aa348 -r eb4d07a0b19f tests/test-prev-next.t diff -r 9871809aa348 -r eb4d07a0b19f tests/test-prune.t --- a/tests/test-prune.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-prune.t Mon Sep 03 21:59:24 2018 +0200 @@ -35,14 +35,20 @@ Check arguments exclusive to each other --------------------------------------- + $ hg prune --fold --pair + abort: can only specify one of pair, fold + [255] $ hg prune --fold --biject - abort: can only specify one of biject, fold + abort: nothing to prune [255] $ hg prune --split --fold abort: can only specify one of fold, split [255] + $ hg prune --split --fold --pair + abort: can only specify one of pair, fold, split + [255] $ hg prune --split --fold --biject - abort: can only specify one of biject, fold, split + abort: can only specify one of fold, split [255] Check simple case @@ -196,7 +202,7 @@ $ hg prune 'desc("add cc")' 'desc("add bb")' -s 'desc("add nD")' -s 'desc("add nC")' abort: Can't use multiple successors for multiple precursors - (use --biject to mark a series as a replacement for another) + (use --pair to mark a series as a replacement for another) [255] $ hg debugobsolete 9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'ef1': '0', 'operation': 'prune', 'user': 'blah'} @@ -223,7 +229,7 @@ 814c38b95e72dfe2cbf675b1649ea9d780c89a80 6f6f25e4f748d8f7571777e6e168aedf50350ce8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '9', 'operation': 'prune', 'user': 'test'} 354011cd103f58bbbd9091a3cee6d6a6bd0dddf7 6f6f25e4f748d8f7571777e6e168aedf50350ce8 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '13', 'operation': 'prune', 'user': 'test'} -two old, two new with --biject +two old, two new with --pair $ hg up 0 0 files updated, 0 files merged, 4 files removed, 0 files unresolved @@ -231,7 +237,7 @@ created new head $ mkcommit n2 - $ hg prune 'desc("add n1")::desc("add n2")' -s 'desc("add nD")::desc("add nE")' --biject + $ hg prune 'desc("add n1")::desc("add n2")' -s 'desc("add nD")::desc("add nE")' --pair 0 files updated, 0 files merged, 2 files removed, 0 files unresolved working directory now at 1f0dee641bb7 2 changesets pruned diff -r 9871809aa348 -r eb4d07a0b19f tests/test-stabilize-result.t --- a/tests/test-stabilize-result.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-stabilize-result.t Mon Sep 03 21:59:24 2018 +0200 @@ -128,8 +128,8 @@ Get a successors of 8 on it - $ hg grab 1cf0aacfd363 - grabbing 6:1cf0aacfd363 "newer a" + $ hg pick 1cf0aacfd363 + picking 6:1cf0aacfd363 "newer a" Add real change to the successors diff -r 9871809aa348 -r eb4d07a0b19f tests/test-stack-branch.t --- a/tests/test-stack-branch.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-stack-branch.t Mon Sep 03 21:59:24 2018 +0200 @@ -56,8 +56,8 @@ 0 files updated, 0 files merged, 4 files removed, 0 files unresolved $ hg stack ### target: other (branch) - b2@ c_b (current) - b1: c_a + s2@ c_b (current) + s1: c_a $ hg phase --public 'branch("other")' $ hg up foo 4 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -71,18 +71,18 @@ foo $ hg stack ### target: foo (branch) - b4@ c_f (current) - b3: c_e - b2: c_d - b1: c_c - b0^ c_b (base) + s4@ c_f (current) + s3: c_e + s2: c_d + s1: c_c + s0^ c_b (base) $ hg stack -v ### target: foo (branch) - b4(913c298d8b0a)@ c_f (current) - b3(4f2a69f6d380): c_e - b2(f61adbacd17a): c_d - b1(3e9313bc4b71): c_c - b0(4a04f1104a27)^ c_b (base) + s4(913c298d8b0a)@ c_f (current) + s3(4f2a69f6d380): c_e + s2(f61adbacd17a): c_d + s1(3e9313bc4b71): c_c + s0(4a04f1104a27)^ c_b (base) Test "t#" reference ------------------- @@ -92,7 +92,7 @@ $ hg up foo 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg up b42 - abort: cannot resolve "b42": branch "foo" has only 4 changesets + abort: cannot resolve "b42": branch "foo" has only 4 non-public changesets [255] $ hg up b2 0 files updated, 0 files merged, 2 files removed, 0 files unresolved @@ -127,20 +127,20 @@ $ hg stack ### target: foo (branch) - b4$ c_f (unstable) - b3$ c_e (unstable) - b2@ c_d (current) - b1: c_c - b0^ c_b (base) + s4$ c_f (unstable) + s3$ c_e (unstable) + s2@ c_d (current) + s1: c_c + s0^ c_b (base) $ hg up b3 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg stack ### target: foo (branch) - b4$ c_f (unstable) - b3$ c_e (current unstable) - b2: c_d - b1: c_c - b0^ c_b (base) + s4$ c_f (unstable) + s3$ c_e (current unstable) + s2: c_d + s1: c_c + s0^ c_b (base) $ hg up b2 1 files updated, 0 files merged, 1 files removed, 0 files unresolved @@ -208,14 +208,14 @@ $ hg stack ### target: foo (branch) (2 heads) - b6@ c_h (current) - b5: c_g - b2^ c_d (base) - b4: c_f - b3: c_e - b2: c_d - b1: c_c - b0^ c_b (base) + s6@ c_h (current) + s5: c_g + s2^ c_d (base) + s4: c_f + s3: c_e + s2: c_d + s1: c_c + s0^ c_b (base) Case with multiple heads on the topic with unstability involved --------------------------------------------------------------- @@ -252,14 +252,14 @@ $ hg stack ### target: foo (branch) (2 heads) - b6: c_h - b5: c_g - b2^ c_D (base current) - b4$ c_f (unstable) - b3$ c_e (unstable) - b2@ c_D (current) - b1: c_c - b0^ c_b (base) + s6: c_h + s5: c_g + s2^ c_D (base current) + s4$ c_f (unstable) + s3$ c_e (unstable) + s2@ c_D (current) + s1: c_c + s0^ c_b (base) Check that stack doesn't show draft changesets on a branch ---------------------------------------------------------- @@ -286,24 +286,24 @@ $ hg stack ### target: foo (branch) (2 heads) - b6: c_h - b5: c_g - b2^ c_D (base current) - b4$ c_f (unstable) - b3$ c_e (unstable) - b2@ c_D (current) - b1: c_c - b0^ c_b (base) + s6: c_h + s5: c_g + s2^ c_D (base current) + s4$ c_f (unstable) + s3$ c_e (unstable) + s2@ c_D (current) + s1: c_c + s0^ c_b (base) $ hg phase --public b1 $ hg stack ### target: foo (branch) (2 heads) - b5: c_h - b4: c_g - b1^ c_D (base current) - b3$ c_f (unstable) - b2$ c_e (unstable) - b1@ c_D (current) - b0^ c_c (base) + s5: c_h + s4: c_g + s1^ c_D (base current) + s3$ c_f (unstable) + s2$ c_e (unstable) + s1@ c_D (current) + s0^ c_c (base) Check that stack doesn't show changeset with a topic ---------------------------------------------------- @@ -312,7 +312,7 @@ changed topic on 2 changes $ hg stack ### target: foo (branch) - b3$ c_f (unstable) - b2$ c_e (unstable) - b1@ c_D (current) - b0^ c_c (base) + s3$ c_f (unstable) + s2$ c_e (unstable) + s1@ c_D (current) + s0^ c_c (base) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic-fold.t --- a/tests/test-topic-fold.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic-fold.t Mon Sep 03 21:59:24 2018 +0200 @@ -55,8 +55,8 @@ $ hg stack ### topic: myfeature ### target: default (branch) - t1@ folded (current) - t0^ add ROOT (base) + s1@ folded (current) + s0^ add ROOT (base) $ logtopic @ 3:4fd43e5bdc443dc8489edffac19bd8f93ccf1a5c | topics: myfeature diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic-rebase.t --- a/tests/test-topic-rebase.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic-rebase.t Mon Sep 03 21:59:24 2018 +0200 @@ -47,8 +47,8 @@ $ hg stack ### topic: myfeature ### target: default (branch) - t1@ add feature1 (current) - t0^ add ROOT (base) + s1@ add feature1 (current) + s0^ add ROOT (base) $ logtopic @ 1:39e7a938055e87615edf675c24a10997ff05bb06 | topics: myfeature @@ -77,8 +77,8 @@ $ hg stack ### topic: myfeature ### target: default (branch) - t1@ add feature1 (current) - t0^ add default (base) + s1@ add feature1 (current) + s0^ add default (base) $ logtopic @ 3:fc6593661cf3256ba165cbccd6019ead17cc3726 | topics: myfeature @@ -91,8 +91,8 @@ $ hg stack ### topic: myfeature ### target: default (branch) - t1@ add feature1 (current) - t0^ add default (base) + s1@ add feature1 (current) + s0^ add default (base) Check that rebase keep the topic in case of merge conflict ---------------------------------------------------------- @@ -157,12 +157,12 @@ $ hg stack ### topic: myotherfeature ### target: default (branch) - t1@ myotherfeature1 (current) - t0^ default3 (base) + s1@ myotherfeature1 (current) + s0^ default3 (base) $ hg update --rev 7 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg stack ### topic: myotherfeature ### target: default (branch) - t1@ myotherfeature1 (current) - t0^ default3 (base) + s1@ myotherfeature1 (current) + s0^ default3 (base) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic-shelve.t --- a/tests/test-topic-shelve.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic-shelve.t Mon Sep 03 21:59:24 2018 +0200 @@ -26,7 +26,7 @@ $ hg stack ### topic: testing-shelve ### target: default (branch) - t1@ First commit (current) + s1@ First commit (current) shelve test ----------- @@ -39,7 +39,7 @@ $ hg stack ### topic: testing-shelve ### target: default (branch) - t1@ First commit (current) + s1@ First commit (current) unshelve test ------------- @@ -50,4 +50,4 @@ $ hg stack ### topic: testing-shelve ### target: default (branch) - t1@ First commit (current) + s1@ First commit (current) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic-stack-complex.t --- a/tests/test-topic-stack-complex.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic-stack-complex.t Mon Sep 03 21:59:24 2018 +0200 @@ -42,10 +42,10 @@ $ hg stack ### topic: foo ### target: default (branch) - t3@ Added e and f (current) - t2: Added c and d - t1: Added a and b - t0^ Added foo (base) + s3@ Added e and f (current) + s2: Added c and d + s1: Added a and b + s0^ Added foo (base) $ hg prev 0 files updated, 0 files merged, 2 files removed, 0 files unresolved [2] Added c and d @@ -86,11 +86,11 @@ $ hg stack ### topic: foo ### target: default (branch) - t4$ Added e and f (unstable) - t3@ split2 (current) - t2: split1 - t1: Added a and b - t0^ Added foo (base) + s4$ Added e and f (unstable) + s3@ split2 (current) + s2: split1 + s1: Added a and b + s0^ Added foo (base) $ hg show work @ 5cce (foo) split2 @@ -129,8 +129,8 @@ $ hg stack ### topic: foo (2 heads) ### target: default (branch), 2 behind - t4$ Added e and f (unstable) - t3$ split2 (unstable) - t2@ split1 (current) - t1: Added a and b - t0^ Added foo (base) + s4$ Added e and f (unstable) + s3$ split2 (unstable) + s2@ split1 (current) + s1: Added a and b + s0^ Added foo (base) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic-stack-data.t --- a/tests/test-topic-stack-data.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic-stack-data.t Mon Sep 03 21:59:24 2018 +0200 @@ -264,39 +264,39 @@ $ hg stack bar ### topic: bar (2 heads) ### target: default (branch) - t5: add bar_c - t2^ add bar_b (base) - t4$ add bar_e (unstable) - t3: bar1_d - t2: add bar_b - t1: add bar_a - t0^ add base_e (base) + s5: add bar_c + s2^ add bar_b (base) + s4$ add bar_e (unstable) + s3: bar1_d + s2: add bar_b + s1: add bar_a + s0^ add base_e (base) $ hg stack bar -v ### topic: bar (2 heads) ### target: default (branch) - t5(9cbadf11b44d): add bar_c - t2(e555c7e8c767)^ add bar_b (base) - t4(a920412b5a05)$ add bar_e (unstable) - t3(6915989374b1): bar1_d - t2(e555c7e8c767): add bar_b - t1(a5c2b4e00bbf): add bar_a - t0(92f489a6251f)^ add base_e (base) + s5(9cbadf11b44d): add bar_c + s2(e555c7e8c767)^ add bar_b (base) + s4(a920412b5a05)$ add bar_e (unstable) + s3(6915989374b1): bar1_d + s2(e555c7e8c767): add bar_b + s1(a5c2b4e00bbf): add bar_a + s0(92f489a6251f)^ add base_e (base) $ hg stack baz ### topic: baz ### target: default (branch), 2 behind - t2: add baz_b - t1: add baz_a - t0^ add base_c (base) + s2: add baz_b + s1: add baz_a + s0^ add base_c (base) $ hg stack foo ### topic: foo ### target: lake (branch), ambiguous rebase destination - branch 'lake' has 2 heads - t2@ add foo_b (current) - t1: add foo_a - t0^ add lake_a (base) + s2@ add foo_b (current) + s1: add foo_a + s0^ add lake_a (base) $ hg stack fuz ### topic: fuz ### target: default (branch), 1 behind - t3$ add fuz_c (unstable) - t2$ add fuz_b (unstable) - t1: fuz1_a - t0^ add base_d (base) + s3$ add fuz_c (unstable) + s2$ add fuz_b (unstable) + s1: fuz1_a + s0^ add base_d (base) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic-stack.t --- a/tests/test-topic-stack.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic-stack.t Mon Sep 03 21:59:24 2018 +0200 @@ -60,8 +60,8 @@ $ hg topic --list ### topic: other ### target: default (branch) - t2@ c_b (current) - t1: c_a + s2@ c_b (current) + s1: c_a $ hg phase --public 'topic("other")' active topic 'other' is now empty (use 'hg topic --clear' to clear it if needed) @@ -75,7 +75,7 @@ ### topic: other ### target: default (branch) (stack is empty) - t0^ c_b (base current) + s0^ c_b (base current) $ hg up foo switching to topic foo @@ -91,19 +91,19 @@ $ hg stack ### topic: foo ### target: default (branch) - t4@ c_f (current) - t3: c_e - t2: c_d - t1: c_c - t0^ c_b (base) + s4@ c_f (current) + s3: c_e + s2: c_d + s1: c_c + s0^ c_b (base) $ hg stack -v ### topic: foo ### target: default (branch) - t4(6559e6d93aea)@ c_f (current) - t3(0f9ac936c87d): c_e - t2(e629654d7050): c_d - t1(8522f9e3fee9): c_c - t0(ea705abc4f51)^ c_b (base) + s4(6559e6d93aea)@ c_f (current) + s3(0f9ac936c87d): c_e + s2(e629654d7050): c_d + s1(8522f9e3fee9): c_c + s0(ea705abc4f51)^ c_b (base) $ hg stack -Tjson | python -m json.tool [ { @@ -213,21 +213,21 @@ $ hg stack ### topic: foo ### target: default (branch) - t4@ c_f (current) - t3: c_e - t2: c_d - t1: c_c - t0^ c_b (base) + s4@ c_f (current) + s3: c_e + s2: c_d + s1: c_c + s0^ c_b (base) $ hg topics --config ui.strict=true * foo (4 changesets) $ hg stack --config ui.strict=true ### topic: foo ### target: default (branch) - t4@ c_f (current) - t3: c_e - t2: c_d - t1: c_c - t0^ c_b (base) + s4@ c_f (current) + s3: c_e + s2: c_d + s1: c_c + s0^ c_b (base) error case, nothing to list @@ -235,21 +235,24 @@ $ hg stack ### target: default (branch) (stack is empty) - b0^ c_f (base current) + s0^ c_f (base current) Test "t#" reference ------------------- - $ hg up t2 - abort: cannot resolve "t2": no active topic + $ hg up s2 + abort: cannot resolve "s2": branch "default" has only 0 non-public changesets [255] $ hg topic foo marked working directory as topic: foo $ hg up t42 abort: cannot resolve "t42": topic "foo" has only 4 changesets [255] - $ hg up t2 + $ hg up s42 + abort: cannot resolve "s42": topic "foo" has only 4 changesets + [255] + $ hg up s2 0 files updated, 0 files merged, 2 files removed, 0 files unresolved $ hg summary parent: 3:e629654d7050 @@ -284,30 +287,30 @@ $ hg topic --list ### topic: foo ### target: default (branch) - t4$ c_f (unstable) - t3$ c_e (unstable) - t2@ c_d (current) - t1: c_c - t0^ c_b (base) - $ hg up t3 + s4$ c_f (unstable) + s3$ c_e (unstable) + s2@ c_d (current) + s1: c_c + s0^ c_b (base) + $ hg up s3 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg topic --list ### topic: foo ### target: default (branch) - t4$ c_f (unstable) - t3$ c_e (current unstable) - t2: c_d - t1: c_c - t0^ c_b (base) + s4$ c_f (unstable) + s3$ c_e (current unstable) + s2: c_d + s1: c_c + s0^ c_b (base) $ hg topic --list --color=debug [topic.stack.summary.topic|### topic: [topic.active|foo]] [topic.stack.summary.branches|### target: default (branch)] - [topic.stack.index topic.stack.index.unstable|t4][topic.stack.state topic.stack.state.unstable|$] [topic.stack.desc topic.stack.desc.unstable|c_f][topic.stack.state topic.stack.state.unstable| (unstable)] - [topic.stack.index topic.stack.index.current topic.stack.index.unstable|t3][topic.stack.state topic.stack.state.current topic.stack.state.unstable|$] [topic.stack.desc topic.stack.desc.current topic.stack.desc.unstable|c_e][topic.stack.state topic.stack.state.current topic.stack.state.unstable| (current unstable)] - [topic.stack.index topic.stack.index.clean|t2][topic.stack.state topic.stack.state.clean|:] [topic.stack.desc topic.stack.desc.clean|c_d] - [topic.stack.index topic.stack.index.clean|t1][topic.stack.state topic.stack.state.clean|:] [topic.stack.desc topic.stack.desc.clean|c_c] - [topic.stack.index topic.stack.index.base|t0][topic.stack.state topic.stack.state.base|^] [topic.stack.desc topic.stack.desc.base|c_b][topic.stack.state topic.stack.state.base| (base)] - $ hg up t2 + [topic.stack.index topic.stack.index.unstable|s4][topic.stack.state topic.stack.state.unstable|$] [topic.stack.desc topic.stack.desc.unstable|c_f][topic.stack.state topic.stack.state.unstable| (unstable)] + [topic.stack.index topic.stack.index.current topic.stack.index.unstable|s3][topic.stack.state topic.stack.state.current topic.stack.state.unstable|$] [topic.stack.desc topic.stack.desc.current topic.stack.desc.unstable|c_e][topic.stack.state topic.stack.state.current topic.stack.state.unstable| (current unstable)] + [topic.stack.index topic.stack.index.clean|s2][topic.stack.state topic.stack.state.clean|:] [topic.stack.desc topic.stack.desc.clean|c_d] + [topic.stack.index topic.stack.index.clean|s1][topic.stack.state topic.stack.state.clean|:] [topic.stack.desc topic.stack.desc.clean|c_c] + [topic.stack.index topic.stack.index.base|s0][topic.stack.state topic.stack.state.base|^] [topic.stack.desc topic.stack.desc.base|c_b][topic.stack.state topic.stack.state.base| (base)] + $ hg up s2 1 files updated, 0 files merged, 1 files removed, 0 files unresolved Also test the revset: @@ -382,14 +385,14 @@ $ hg top -l ### topic: foo (2 heads) ### target: default (branch) - t6@ c_h (current) - t5: c_g - t2^ c_d (base) - t4: c_f - t3: c_e - t2: c_d - t1: c_c - t0^ c_b (base) + s6@ c_h (current) + s5: c_g + s2^ c_d (base) + s4: c_f + s3: c_e + s2: c_d + s1: c_c + s0^ c_b (base) Case with multiple heads on the topic with unstability involved --------------------------------------------------------------- @@ -427,14 +430,14 @@ $ hg topic --list ### topic: foo (2 heads) ### target: default (branch) - t6: c_h - t5: c_g - t2^ c_D (base current) - t4$ c_f (unstable) - t3$ c_e (unstable) - t2@ c_D (current) - t1: c_c - t0^ c_b (base) + s6: c_h + s5: c_g + s2^ c_D (base current) + s4$ c_f (unstable) + s3$ c_e (unstable) + s2@ c_D (current) + s1: c_c + s0^ c_b (base) Trying to list non existing topic $ hg stack thisdoesnotexist @@ -553,21 +556,21 @@ $ hg stack ### topic: foobar ### target: default (branch), 3 behind - t2@ c_e (current) + s2@ c_e (current) ^ c_h - t1: c_D - t0^ c_c (base) + s1: c_D + s0^ c_c (base) $ hg stack foo ### topic: foo ### target: default (branch), ambiguous rebase destination - topic 'foo' has 3 heads - t4: c_f + s4: c_f ^ c_e - t3: c_h - t2: c_g + s3: c_h + s2: c_g ^ c_D - t1: c_c - t0^ c_b (base) + s1: c_c + s0^ c_b (base) case involving a merge ---------------------- @@ -643,24 +646,24 @@ $ hg stack red ### topic: red ### target: default (branch), 6 behind - t5: c_H + s5: c_H ^ c_G ^ c_D - t4: c_C - t1^ c_B (base) - t3: c_F - t2: c_E - t1: c_B - t0^ c_A (base) + s4: c_C + s1^ c_B (base) + s3: c_F + s2: c_E + s1: c_B + s0^ c_A (base) $ hg stack blue ### topic: blue ### target: default (branch), ambiguous rebase destination - topic 'blue' has 3 heads - t3@ c_I (current) + s3@ c_I (current) ^ c_H - t2: c_D + s2: c_D ^ c_C - t1: c_G - t0^ c_F (base) + s1: c_G + s0^ c_F (base) Even with some obsolete and orphan changesets @@ -709,24 +712,24 @@ $ hg stack red ### topic: red ### target: default (branch), ambiguous rebase destination - topic 'red' has 3 heads - t5$ c_H (unstable) + s5$ c_H (unstable) ^ c_G ^ c_D - t4$ c_C (unstable) - t1^ c_B (base) - t3$ c_F (unstable) - t2$ c_E (unstable) - t1: c_B - t0^ c_A (base) + s4$ c_C (unstable) + s1^ c_B (base) + s3$ c_F (unstable) + s2$ c_E (unstable) + s1: c_B + s0^ c_A (base) $ hg stack blue ### topic: blue ### target: default (branch), ambiguous rebase destination - topic 'blue' has 3 heads - t3$ c_I (unstable) + s3$ c_I (unstable) ^ c_H - t2$ c_G (unstable) + s2$ c_G (unstable) ^ c_F - t1$ c_D (current unstable) - t0^ c_C (base unstable) + s1$ c_D (current unstable) + s0^ c_C (base unstable) more obsolescence @@ -783,49 +786,49 @@ $ hg stack red ### topic: red ### target: default (branch), ambiguous rebase destination - topic 'red' has 3 heads - t5$ c_H (unstable) + s5$ c_H (unstable) ^ c_G ^ c_D - t4$ c_F (unstable) - t3$ c_E (unstable) - t1^ c_B (base) - t2$ c_C (unstable) - t1: c_B - t0^ c_A (base) + s4$ c_F (unstable) + s3$ c_E (unstable) + s1^ c_B (base) + s2$ c_C (unstable) + s1: c_B + s0^ c_A (base) $ hg stack blue ### topic: blue ### target: default (branch), ambiguous rebase destination - topic 'blue' has 3 heads - t3$ c_I (unstable) + s3$ c_I (unstable) ^ c_H - t2$ c_G (unstable) + s2$ c_G (unstable) ^ c_F - t1$ c_D (current unstable) - t0^ c_C (base unstable) + s1$ c_D (current unstable) + s0^ c_C (base unstable) Test stack behavior with a split -------------------------------- get things linear again - $ hg rebase -r t1 -d default + $ hg rebase -r s1 -d default rebasing 16:1d84ec948370 "c_D" (tip blue) switching to topic blue - $ hg rebase -r t2 -d t1 + $ hg rebase -r s2 -d s1 rebasing 13:3ab2eedae500 "c_G" (blue) - $ hg rebase -r t3 -d t2 + $ hg rebase -r s3 -d s2 rebasing 8:3bfe800e0486 "c_I" (blue) $ hg stack ### topic: blue ### target: default (branch) - t3: c_I - t2: c_G - t1@ c_D (current) - t0^ c_A (base) + s3: c_I + s2: c_G + s1@ c_D (current) + s0^ c_A (base) making a split (first get something to split) - $ hg up t2 + $ hg up s2 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg status --change . A ggg @@ -839,10 +842,10 @@ $ hg stack ### topic: blue ### target: default (branch) - t3$ c_I (unstable) - t2@ c_G (current) - t1: c_D - t0^ c_A (base) + s3$ c_I (unstable) + s2@ c_G (current) + s1: c_D + s0^ c_A (base) $ hg --config extensions.evolve= --config ui.interactive=yes split << EOF > y > y @@ -919,8 +922,8 @@ $ hg stack ### topic: blue ### target: default (branch) - t4$ c_I (unstable) - t3@ c_G (current) - t2: c_G - t1: c_D - t0^ c_A (base) + s4$ c_I (unstable) + s3@ c_G (current) + s2: c_G + s1: c_D + s0^ c_A (base) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic-tutorial.t --- a/tests/test-topic-tutorial.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic-tutorial.t Mon Sep 03 21:59:24 2018 +0200 @@ -252,9 +252,9 @@ $ hg stack ### topic: food ### target: default (branch) - t2@ adding fruits (current) - t1: adding condiments - t0^ Shopping list (base) + s2@ adding fruits (current) + s1: adding condiments + s0^ Shopping list (base) The topic deactivates when we update away from it: @@ -614,7 +614,7 @@ ### topic: food ### target: default (branch) (stack is empty) - t0^ adding fruits (base current) + s0^ adding fruits (base current) $ hg log --graph @ changeset: 5:2d50db8b5b4c @@ -791,9 +791,9 @@ $ hg stack ### topic: drinks ### target: default (branch) - t2@ Adding orange juice (current) - t1: Adding apple juice - t0^ adding fruits (base) + s2@ Adding orange juice (current) + s1: Adding apple juice + s0^ adding fruits (base) $ hg update tools switching to topic tools @@ -802,10 +802,10 @@ $ hg stack ### topic: tools ### target: default (branch) - t3@ Adding drill (current) - t2: Adding saw - t1: Adding hammer - t0^ adding fruits (base) + s3@ Adding drill (current) + s2: Adding saw + s1: Adding hammer + s0^ adding fruits (base) They are seen as independent branches by Mercurial. No rebase or merge between them will be attempted by default: @@ -1121,10 +1121,10 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3@ Adding drill (current) - t2: Adding saw - t1: Adding hammer - t0^ add a pair of shoes (base) + s3@ Adding drill (current) + s2: Adding saw + s1: Adding hammer + s0^ add a pair of shoes (base) Working Within Your Stack =========================== @@ -1140,10 +1140,10 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3@ Adding drill (current) - t2: Adding saw - t1: Adding hammer - t0^ add a pair of shoes (base) + s3@ Adding drill (current) + s2: Adding saw + s1: Adding hammer + s0^ add a pair of shoes (base) You can navigate in your current stack with `previous` and `next`. @@ -1156,10 +1156,10 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3: Adding drill - t2@ Adding saw (current) - t1: Adding hammer - t0^ add a pair of shoes (base) + s3: Adding drill + s2@ Adding saw (current) + s1: Adding hammer + s0^ add a pair of shoes (base) `next` will move you forward to the topic head. @@ -1170,23 +1170,23 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3@ Adding drill (current) - t2: Adding saw - t1: Adding hammer - t0^ add a pair of shoes (base) + s3@ Adding drill (current) + s2: Adding saw + s1: Adding hammer + s0^ add a pair of shoes (base) You can also directly jump to a changeset within your stack with the revset `t#`. - $ hg update t1 + $ hg update s1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3: Adding drill - t2: Adding saw - t1@ Adding hammer (current) - t0^ add a pair of shoes (base) + s3: Adding drill + s2: Adding saw + s1@ Adding hammer (current) + s0^ add a pair of shoes (base) Editing your work mid-stack --------------------------- @@ -1196,10 +1196,10 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3: Adding drill - t2: Adding saw - t1@ Adding hammer (current) - t0^ add a pair of shoes (base) + s3: Adding drill + s2: Adding saw + s1@ Adding hammer (current) + s0^ add a pair of shoes (base) $ hg amend -m "Adding hammer to the shopping list" 2 new orphan changesets @@ -1207,7 +1207,7 @@ Understanding the current situation with hg log is not so easy, because it shows too many things: - $ hg log -G -r "t0::" + $ hg log -G -r "s0::" @ changeset: 18:b7509bd417f8 | tag: tip | topic: tools @@ -1255,7 +1255,7 @@ #if docgraph-ext - $ hg docgraph -r "t0::" --sphinx-directive --rankdir LR #rest-ignore + $ hg docgraph -r "s0::" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { @@ -1358,13 +1358,13 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3$ Adding drill (unstable) - t2$ Adding saw (unstable) - t1@ Adding hammer to the shopping list (current) - t0^ add a pair of shoes (base) + s3$ Adding drill (unstable) + s2$ Adding saw (unstable) + s1@ Adding hammer to the shopping list (current) + s0^ add a pair of shoes (base) It's easy to stabilize the situation, `next` has an `--evolve` option. It will -do the necessary relocation of `t2` and `t3` over the new `t1` without having +do the necessary relocation of `s2` and `s3` over the new `s1` without having to do that rebase by hand.: $ hg next --evolve @@ -1375,10 +1375,10 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3$ Adding drill (unstable) - t2@ Adding saw (current) - t1: Adding hammer to the shopping list - t0^ add a pair of shoes (base) + s3$ Adding drill (unstable) + s2@ Adding saw (current) + s1: Adding hammer to the shopping list + s0^ add a pair of shoes (base) One more to go: @@ -1390,14 +1390,14 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t3@ Adding drill (current) - t2: Adding saw - t1: Adding hammer to the shopping list - t0^ add a pair of shoes (base) + s3@ Adding drill (current) + s2: Adding saw + s1: Adding hammer to the shopping list + s0^ add a pair of shoes (base) Let's take a look at `hg log` once again: - $ hg log -G -r "t0::" + $ hg log -G -r "s0::" @ changeset: 20:bae3758e46bf | tag: tip | topic: tools @@ -1436,7 +1436,7 @@ #if docgraph-ext - $ hg docgraph -r "t0::" --sphinx-directive --rankdir LR #rest-ignore + $ hg docgraph -r "s0::" --sphinx-directive --rankdir LR #rest-ignore .. graphviz:: strict digraph "Mercurial graph" { @@ -1521,7 +1521,7 @@ Stack is also very helpful when you have a multi-headed stack: - $ hg up t1 + $ hg up s1 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo "nails" > new_shopping @@ -1533,12 +1533,12 @@ $ hg stack ### topic: tools (2 heads) ### target: default (branch), 2 behind - t4: Adding drill - t3: Adding saw - t1^ Adding hammer to the shopping list (base) - t2@ Adding nails (current) - t1: Adding hammer to the shopping list - t0^ add a pair of shoes (base) + s4: Adding drill + s3: Adding saw + s1^ Adding hammer to the shopping list (base) + s2@ Adding nails (current) + s1: Adding hammer to the shopping list + s0^ add a pair of shoes (base) Solving this situation is easy with a topic: use merge or rebase. Merge within a multi-headed stack will use the other topic head as @@ -1771,7 +1771,7 @@ } #endif - $ hg up t4 + $ hg up s4 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg rebase @@ -1783,11 +1783,11 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t4@ Adding drill (current) - t3: Adding saw - t2: Adding nails - t1: Adding hammer to the shopping list - t0^ add a pair of shoes (base) + s4@ Adding drill (current) + s3: Adding saw + s2: Adding nails + s1: Adding hammer to the shopping list + s0^ add a pair of shoes (base) Collaborating through a non-publishing server ============================================= @@ -1858,11 +1858,11 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t4@ Adding drill (current) - t3: Adding saw - t2: Adding nails - t1: Adding hammer to the shopping list - t0^ add a pair of shoes (base) + s4@ Adding drill (current) + s3: Adding saw + s2: Adding nails + s1: Adding hammer to the shopping list + s0^ add a pair of shoes (base) We can also add new changesets and share them: @@ -1898,9 +1898,9 @@ $ hg stack ### topic: tools ### target: default (branch), 2 behind - t5@ Adding screws (current) - t4: Adding drill - t3: Adding saw - t2: Adding nails - t1: Adding hammer to the shopping list - t0^ add a pair of shoes (base) + s5@ Adding screws (current) + s4: Adding drill + s3: Adding saw + s2: Adding nails + s1: Adding hammer to the shopping list + s0^ add a pair of shoes (base) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-topic.t --- a/tests/test-topic.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-topic.t Mon Sep 03 21:59:24 2018 +0200 @@ -40,8 +40,10 @@ your current topic. Topic is offering you aliases reference to changeset in your current topic - stack as 't#'. For example, 't1' refers to the root of your stack, 't2' to the - second commits, etc. The 'hg stack' command show these number. + stack as 's#'. For example, 's1' refers to the root of your stack, 's2' to the + second commits, etc. The 'hg stack' command show these number. 's0' can be + used to refer to the parent of the topic root. Updating using 'hg up s0' will + keep the topic active. Push behavior will change a bit with topic. When pushing to a publishing repository the changesets will turn public and the topic data on them will @@ -271,7 +273,7 @@ ### topic: narf ### target: default (branch) (stack is empty) - t0^ Add file delta (base current) + s0^ Add file delta (base current) Add commits to topic @@ -695,7 +697,7 @@ summary: Add file alpha No matches because narf is already closed: - $ hg log -r 'topic(narf)' -G + $ hg log -r 'topic("narf")' -G This regexp should match the topic `fran`: $ hg log -r 'topic("re:.ra.")' -G o changeset: 9:0469d521db49 @@ -735,10 +737,39 @@ summary: start on fran +Using revsets in topic() + $ tlog() { + > hg log -T '{rev}: {topic}\n' -r "$1" + > } + + $ tlog 'topic(9)' + 9: fran + $ tlog 'topic(8)' + $ tlog 'topic(head())' + 9: fran + $ tlog 'topic(:)' + 9: fran + $ tlog 'topic(all())' + 9: fran + $ tlog 'topic(topic(fran))' + 9: fran + $ tlog 'topic(wdir())' + 9: fran + $ tlog 'topic(nonsense)' + abort: unknown revision 'nonsense'! + [255] + +Pattern matching in topic() revset + $ tlog 'topic("re:nonsense")' + $ tlog 'topic("literal:nonsense")' + abort: topic 'nonsense' does not exist! + [255] + Deactivate the topic. $ hg topics * fran (1 changesets) $ hg topics --clear + $ hg log -r 'topic(wdir())' $ echo fran? >> beta $ hg ci -m 'fran?' created new head @@ -761,7 +792,7 @@ $ hg topics fran (1 changesets) -Testing for updating to t0 +Testing for updating to s0 ========================== $ hg up fran @@ -770,10 +801,10 @@ $ hg stack ### topic: fran ### target: default (branch), ambiguous rebase destination - branch 'default' has 2 heads - t1@ start on fran (current) - t0^ Add file delta (base) + s1@ start on fran (current) + s0^ Add file delta (base) - $ hg up t0 + $ hg up s0 preserving the current topic 'fran' 1 files updated, 0 files merged, 0 files removed, 0 files unresolved @@ -782,8 +813,8 @@ $ hg stack ### topic: fran ### target: default (branch), ambiguous rebase destination - branch 'default' has 2 heads - t1: start on fran - t0^ Add file delta (base current) + s1: start on fran + s0^ Add file delta (base current) $ hg topics --age * fran (1970-01-01 by test) diff -r 9871809aa348 -r eb4d07a0b19f tests/test-tutorial.t --- a/tests/test-tutorial.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-tutorial.t Mon Sep 03 21:59:24 2018 +0200 @@ -664,8 +664,8 @@ $ hg up 'p1(10b8aeaa8cc8)' # going on "bathroom stuff" parent 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg grab fac207dec9f5 # moving "SPAM SPAM" to the working directory parent - grabbing 9:fac207dec9f5 "SPAM SPAM" + $ hg pick fac207dec9f5 # moving "SPAM SPAM" to the working directory parent + picking 9:fac207dec9f5 "SPAM SPAM" merging shopping $ hg log -G @ 57e9caedbcb8 (draft): SPAM SPAM @@ -806,8 +806,8 @@ for simplicity sake we get the bathroom change in line again - $ hg grab 10b8aeaa8cc8 - grabbing 8:10b8aeaa8cc8 "bathroom stuff" + $ hg pick 10b8aeaa8cc8 + picking 8:10b8aeaa8cc8 "bathroom stuff" merging shopping $ hg phase --draft . $ hg log -G diff -r 9871809aa348 -r eb4d07a0b19f tests/test-wireproto.t --- a/tests/test-wireproto.t Tue Aug 28 11:24:49 2018 +0200 +++ b/tests/test-wireproto.t Mon Sep 03 21:59:24 2018 +0200 @@ -195,7 +195,7 @@ $ cat hg.pid >> $DAEMON_PIDS $ curl -s http://localhost:$HGPORT/?cmd=capabilities - _evoext_getbundle_obscommon batch branchmap bundle2=HG20%0Abookmarks%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Aobsmarkers%3DV0%2CV1%0Aphases%3Dheads%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps%0Arev-branch-cache changegroupsubset compression=*zlib getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-eol) (glob) + _evoext_getbundle_obscommon _evoext_obshashrange_v1 batch branchmap bundle2=HG20%0Abookmarks%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Aobsmarkers%3DV0%2CV1%0Aphases%3Dheads%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps%0Arev-branch-cache changegroupsubset compression=*zlib getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (no-eol) (glob) Check we cannot use pushkey for marker exchange anymore @@ -215,7 +215,6 @@ pulling from http://localhost:$HGPORT/ searching for changes no changes found - obsmarker-exchange: 274 bytes received $ hg -R client pull http://localhost:$HGPORT/ --config experimental.evolution=createmarkers pulling from http://localhost:$HGPORT/