# HG changeset patch # User Pierre-Yves David # Date 1513013415 -3600 # Node ID bd99cb54712b672fee730b359d6cfc7e0e5c5caf # Parent b714709afe6ab8cdab6a745167d24eaacc24309a# Parent 875de4816c5b8c815f01f680a262b12298c64f87 test-compat: merge mercurial-4.2 into mercurial-4.1 diff -r 875de4816c5b -r bd99cb54712b CHANGELOG --- a/CHANGELOG Mon Dec 11 09:33:32 2017 +0100 +++ b/CHANGELOG Mon Dec 11 18:30:15 2017 +0100 @@ -1,6 +1,22 @@ Changelog ========= +7.1.0 - in progress +------------------- + + * verbosity: respect --quiet for prev, next and summary + * note: add a `-n/--note` flag to all history rewritting commands + * obslog: shows the obsmarkers notes + * obsdiscover: Improved stable range slice for the experimental obshashrange + (client and server need to upgrade to this version) + +topic (0.6.0) + + * add a new 'serverminitopic' extension for minimal server support + (see `hg help -e serverminitopic` for details) + * add a new config option `experimental.topic-mode.server` using which a + server can reject draft changesets without topic + 7.0.2 - in progress ------------------- @@ -8,7 +24,9 @@ Topic (0.5.2) + * fix behavior of `hg stack` in cases of split * makes code more resilient to partiel initialization + * avoid over wrapping inside of long living process 7.0.1 -- 2017-11-14 ------------------- diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/__init__.py --- a/hgext3rd/evolve/__init__.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/evolve/__init__.py Mon Dec 11 18:30:15 2017 +0100 @@ -831,17 +831,10 @@ raise def summaryhook(ui, repo): - def write(fmt, count): - s = fmt % count - if count: - ui.write(s) - else: - ui.note(s) - state = _evolvestateread(repo) if state is not None: # i18n: column positioning for "hg summary" - ui.write(_('evolve: (evolve --continue)\n')) + ui.status(_('evolve: (evolve --continue)\n')) @eh.extsetup def obssummarysetup(ui): @@ -2031,7 +2024,8 @@ finally: lockmod.release(tr, lock) - displayer.show(target) + if not repo.ui.quiet: + displayer.show(target) def _findprevtarget(repo, displayer, movebookmark=False, topic=True): target = bookmark = None @@ -2174,7 +2168,8 @@ tr.close() finally: lockmod.release(tr, lock) - displayer.show(c) + if not ui.quiet: + displayer.show(c) result = 0 elif children: ui.warn(_("ambiguous next changeset:\n")) diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/cmdrewrite.py --- a/hgext3rd/evolve/cmdrewrite.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/evolve/cmdrewrite.py Mon Dec 11 18:30:15 2017 +0100 @@ -49,6 +49,21 @@ # option added by evolve +def _checknotesize(ui, opts): + """ make sure note is of valid format """ + + note = opts.get('note') + if not note: + return + + if not compat.isobsnotesupported(): + ui.warn(_("current hg version does not support storing" + " note in obsmarker\n")) + if len(note) > 255: + raise error.Abort(_("cannot store a note of more than 255 bytes")) + if '\n' in note: + raise error.Abort(_("note cannot contain a newline")) + def _resolveoptions(ui, opts): """modify commit options dict to handle related options @@ -80,6 +95,7 @@ ('', 'close-branch', None, _('mark a branch as closed, hiding it from the branch list')), ('s', 'secret', None, _('use the secret phase for committing')), + ('n', 'note', '', _('store a note on amend')), ] + walkopts + commitopts + commitopts2 + commitopts3 + interactiveopt, _('[OPTION]... [FILE]...')) def amend(ui, repo, *pats, **opts): @@ -98,6 +114,7 @@ Returns 0 on success, 1 if nothing changed. """ + _checknotesize(ui, opts) opts = opts.copy() if opts.get('extract'): return uncommit(ui, repo, *pats, **opts) @@ -288,6 +305,7 @@ [('a', 'all', None, _('uncommit all changes when no arguments given')), ('i', 'interactive', False, _('interactive mode to uncommit (EXPERIMENTAL)')), ('r', 'rev', '', _('revert commit content to REV instead')), + ('n', 'note', '', _('store a note on uncommit')), ] + commands.walkopts + commitopts + commitopts2 + commitopts3, _('[OPTION]... [NAME]')) def uncommit(ui, repo, *pats, **opts): @@ -313,6 +331,7 @@ Return 0 if changed files are uncommitted. """ + _checknotesize(ui, opts) _resolveoptions(ui, opts) # process commitopts3 interactive = opts.get('interactive') wlock = lock = tr = None @@ -365,7 +384,12 @@ raise error.Abort(_('nothing to uncommit'), hint=_("use --all to uncommit all files")) - obsolete.createmarkers(repo, [(old, (repo[newid],))]) + # metadata to be stored in obsmarker + metadata = {} + if opts.get('note'): + metadata['note'] = opts['note'] + + obsolete.createmarkers(repo, [(old, (repo[newid],))], metadata=metadata) phases.retractboundary(repo, tr, oldphase, [newid]) with repo.dirstate.parentchange(): repo.dirstate.setparents(newid, node.nullid) @@ -477,7 +501,8 @@ '^fold|squash', [('r', 'rev', [], _("revision to fold")), ('', 'exact', None, _("only fold specified revisions")), - ('', 'from', None, _("fold revisions linearly to working copy parent")) + ('', 'from', None, _("fold revisions linearly to working copy parent")), + ('n', 'note', '', _('store a note on fold')), ] + commitopts + commitopts2 + commitopts3, _('hg fold [OPTION]... [-r] REV')) def fold(ui, repo, *revs, **opts): @@ -517,6 +542,7 @@ hg fold foo::@ --exact """ + _checknotesize(ui, opts) _resolveoptions(ui, opts) revs = list(revs) revs.extend(opts['rev']) @@ -572,6 +598,10 @@ commitopts['message'] = "\n".join(msgs) commitopts['edit'] = True + metadata = {} + if opts.get('note'): + metadata['note'] = opts['note'] + newid, unusedvariable = rewriteutil.rewrite(repo, root, allctx, head, [root.p1().node(), @@ -579,7 +609,7 @@ commitopts=commitopts) phases.retractboundary(repo, tr, targetphase, [newid]) obsolete.createmarkers(repo, [(ctx, (repo[newid],)) - for ctx in allctx]) + for ctx in allctx], metadata=metadata) tr.close() finally: tr.release() @@ -593,6 +623,7 @@ 'metaedit', [('r', 'rev', [], _("revision to edit")), ('', 'fold', None, _("also fold specified revisions into one")), + ('n', 'note', '', _('store a note on metaedit')), ] + commitopts + commitopts2 + commitopts3, _('hg metaedit [OPTION]... [-r] [REV]')) def metaedit(ui, repo, *revs, **opts): @@ -624,6 +655,7 @@ See :hg:`help phases` for more about draft revisions, and :hg:`help revsets` for more about the `draft()` and `only()` keywords. """ + _checknotesize(ui, opts) _resolveoptions(ui, opts) revs = list(revs) revs.extend(opts['rev']) @@ -697,9 +729,15 @@ if created: if p1.rev() in revs: newp1 = newid + # metadata to be stored on obsmarker + metadata = {} + if opts.get('note'): + metadata['note'] = opts['note'] + phases.retractboundary(repo, tr, targetphase, [newid]) obsolete.createmarkers(repo, [(ctx, (repo[newid],)) - for ctx in allctx]) + for ctx in allctx], + metadata=metadata) else: ui.status(_("nothing changed\n")) tr.close() @@ -736,6 +774,7 @@ ('s', 'succ', [], _("successor changeset")), ('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")), ('', 'fold', False, _("record a fold (multiple precursors, one successors)")), @@ -769,6 +808,7 @@ must acknowledge it by passing ``--split``. Similarly, when you prune multiple changesets with a single successor, you must pass the ``--fold`` option. """ + _checknotesize(ui, opts) revs = scmutil.revrange(repo, list(revs) + opts.get('rev')) succs = opts['new'] + opts['succ'] bookmarks = set(opts.get('bookmark')) @@ -884,6 +924,10 @@ if bookmarks: rewriteutil.deletebookmark(repo, repomarks, bookmarks) + # store note in metadata + if opts.get('note'): + metadata['note'] = opts['note'] + # create markers obsolete.createmarkers(repo, relations, metadata=metadata) @@ -913,6 +957,7 @@ @eh.command( '^split', [('r', 'rev', [], _("revision to split")), + ('n', 'note', '', _("store a note on split")), ] + commitopts + commitopts2 + commitopts3, _('hg split [OPTION]... [-r] REV')) def cmdsplit(ui, repo, *revs, **opts): @@ -923,6 +968,7 @@ Use --rev to split a given changeset instead. """ + _checknotesize(ui, opts) _resolveoptions(ui, opts) tr = wlock = lock = None newcommits = [] @@ -992,7 +1038,11 @@ bmupdate(tip.node()) if bookactive is not None: bookmarksmod.activate(repo, bookactive) - obsolete.createmarkers(repo, [(repo[rev], newcommits)]) + metadata = {} + if opts.get('note'): + metadata['note'] = opts['note'] + obsolete.createmarkers(repo, [(repo[rev], newcommits)], + metadata=metadata) tr.close() finally: # Restore the old branch @@ -1003,6 +1053,7 @@ @eh.command( 'touch', [('r', 'rev', [], 'revision to update'), + ('n', 'note', '', _('store a note on touch')), ('D', 'duplicate', False, 'do not mark the new revision as successor of the old one'), ('A', 'allowdivergence', False, @@ -1015,6 +1066,7 @@ This is used to "resurrect" changesets """ + _checknotesize(ui, opts) duplicate = opts['duplicate'] allowdivergence = opts['allowdivergence'] revs = list(revs) @@ -1078,7 +1130,11 @@ newmapping[ctx.node()] = new if not duplicate: - obsolete.createmarkers(repo, [(ctx, (repo[new],))]) + metadata = {} + if opts.get('note'): + metadata['note'] = opts['note'] + obsolete.createmarkers(repo, [(ctx, (repo[new],))], + metadata=metadata) phases.retractboundary(repo, tr, ctx.phase(), [new]) if ctx in repo[None].parents(): with repo.dirstate.parentchange(): diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/compat.py --- a/hgext3rd/evolve/compat.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/evolve/compat.py Mon Dec 11 18:30:15 2017 +0100 @@ -97,6 +97,14 @@ bookmarks[name] = node bookmarks.recordchange(tr) +def isobsnotesupported(): + # hack to know obsnote is supported. The patches for obsnote support was + # pushed before the obsfateprinter patches, so this will serve as a good + # check + if not obsutil: + return False + return util.safehasattr(obsutil, 'obsfateprinter') + # Evolution renaming compat TROUBLES = {} diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/depthcache.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/evolve/depthcache.py Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,228 @@ +from __future__ import absolute_import + +import array +import weakref + +from mercurial import ( + localrepo, + node as nodemod, + util, + scmutil, +) + +from . import ( + error, + exthelper, + genericcaches, +) + +from mercurial.i18n import _ + +eh = exthelper.exthelper() + +def simpledepth(repo, rev): + """simple but obviously right implementation of depth""" + return len(repo.revs('::%d', rev)) + +@eh.command( + 'debugdepth', + [ + ('r', 'rev', [], 'revs to print depth for'), + ('', 'method', 'cached', "one of 'simple', 'cached', 'compare'"), + ], + _('REVS')) +def debugdepth(ui, repo, **opts): + """display depth of REVS + """ + revs = scmutil.revrange(repo, opts['rev']) + method = opts['method'] + if method == 'cached': + cache = repo.depthcache + cache.save(repo) + for r in revs: + ctx = repo[r] + if method == 'simple': + depth = simpledepth(repo, r) + elif method == 'cached': + depth = cache.get(r) + elif method == 'compare': + simple = simpledepth(repo, r) + cached = cache.get(r) + if simple != cached: + raise error.Abort('depth differ for revision %s: %d != %d' + % (ctx, simple, cached)) + else: + raise error.Abort('unknown method "%s"' % method) + ui.write('%s %d\n' % (ctx, depth)) + +@eh.reposetup +def setupcache(ui, repo): + + class depthcacherepo(repo.__class__): + + @localrepo.unfilteredpropertycache + def depthcache(self): + cache = depthcache() + cache.update(self) + return cache + + @localrepo.unfilteredmethod + def destroyed(self): + if 'obsstore' in vars(self): + self.depthcache.clear() + super(depthcacherepo, self).destroyed() + + if util.safehasattr(repo, 'updatecaches'): + @localrepo.unfilteredmethod + def updatecaches(self, tr=None): + if (repo.ui.configbool('experimental', 'obshashrange', + False) + and repo.ui.configbool('experimental', + 'obshashrange.warm-cache', + True)): + self.depthcache.update(repo) + self.depthcache.save(repo) + super(depthcacherepo, self).updatecaches(tr) + + 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() + # 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) + + if (repo.ui.configbool('experimental', 'obshashrange', + False) + and repo.ui.configbool('experimental', + 'obshashrange.warm-cache', + True)): + tr.addpostclose('warmcache-depthcache', _warmcache) + return tr + + repo.__class__ = depthcacherepo + +class depthcache(genericcaches.changelogsourcebase): + + _filepath = 'evoext-depthcache-00' + _cachename = 'evo-ext-depthcache' + + def __init__(self): + super(depthcache, self).__init__() + self._data = array.array('l') + + def get(self, rev): + if len(self._data) <= rev: + raise error.ProgrammingError('depthcache must be warmed before use') + return self._data[rev] + + def _updatefrom(self, repo, data): + """compute the rev of one revision, assert previous revision has an hot cache + """ + cl = repo.unfiltered().changelog + total = len(data) + + def progress(pos, rev): + repo.ui.progress('updating depth cache', + pos, 'rev %s' % rev, unit='revision', total=total) + progress(0, '') + for idx, rev in enumerate(data, 1): + assert rev == len(self._data), (rev, len(self._data)) + self._data.append(self._depth(cl, rev)) + if not (idx % 10000): # progress as a too high performance impact + progress(idx, rev) + progress(None, '') + + def _depth(self, changelog, rev): + cl = changelog + p1, p2 = cl.parentrevs(rev) + if p1 == nodemod.nullrev: + # root case + return 1 + elif p2 == nodemod.nullrev: + # linear commit case + return self.get(p1) + 1 + # merge case, must find the amount of exclusive content + depth_p1 = self.get(p1) + depth_p2 = self.get(p2) + # computing depth of a merge + ancnodes = cl.commonancestorsheads(cl.node(p1), cl.node(p2)) + if not ancnodes: + # unrelated branch, (no common root) + revdepth = depth_p1 + depth_p2 + 1 + elif len(ancnodes) == 1: + # one unique branch point: + # we can compute depth without any walk + ancrev = cl.rev(ancnodes[0]) + depth_anc = self.get(ancrev) + revdepth = depth_p1 + (depth_p2 - depth_anc) + 1 + else: + # we pick the parent that is that is + # * the deepest (less changeset outside of it), + # * lowest revs because more chance to have descendant of other "above" + parents = [(p1, depth_p1), (p2, depth_p2)] + parents.sort(key=lambda x: (x[1], -x[0])) + revdepth = parents[1][1] + revdepth += len(cl.findmissingrevs(common=[parents[1][0]], + heads=[parents[0][0]])) + revdepth += 1 # the merge revision + return revdepth + + # cache internal logic + + def clear(self, reset=False): + """invalidate the cache content + + if 'reset' is passed, we detected a strip and the cache will have to be + recomputed. + + Subclasses MUST overide this method to actually affect the cache data. + """ + super(depthcache, self).clear() + self._data = array.array('l') + + # crude version of a cache, to show the kind of information we have to store + + def load(self, repo): + """load data from disk""" + assert repo.filtername is None + + if util.safehasattr(repo, 'cachevfs'): + data = repo.cachevfs.tryread(self._filepath) + else: + data = repo.vfs.tryread('cache/' + self._filepath) + self._data = array.array('l') + if not data: + self._cachekey = self.emptykey + else: + headerdata = data[:self._cachekeysize] + self._cachekey = self._deserializecachekey(headerdata) + self._data.fromstring(data[self._cachekeysize:]) + self._ondiskkey = self._cachekey + + def save(self, repo): + """save the data to disk + + Format is pretty simple, we serialise the cache key and then drop the + bytearray. + """ + if self._cachekey is None or self._cachekey == self._ondiskkey: + return + + if util.safehasattr(repo, 'cachevfs'): + cachefile = repo.cachevfs(self._filepath, 'w', atomictemp=True) + else: + cachefile = repo.vfs('cache/' + self._filepath, 'w', atomictemp=True) + headerdata = self._serializecachekey() + cachefile.write(headerdata) + cachefile.write(self._data.tostring()) + cachefile.close() diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/genericcaches.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/evolve/genericcaches.py Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,188 @@ +# cache.py - utilities for caching +# +# Copyright 2017 Octobus SAS +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. +from __future__ import absolute_import + +import abc +import struct +import time +import os + +from mercurial import ( + node, + pycompat, + util, +) + +# prior to hg-4.2 there are not util.timer +if util.safehasattr(util, 'timer'): + timer = util.timer +elif util.safehasattr(time, "perf_counter"): + timer = time.perf_counter +elif getattr(pycompat, 'osname', os.name) == 'nt': + timer = time.clock +else: + timer = time.time + +class incrementalcachebase(object): + """base class for incremental cache from append only source + + There are multiple append only data source we might want to cache + computation from. One of the common pattern is to track the state of the + file and update the cache with the extra data (eg: branchmap-cache tracking + changelog). This pattern also needs to detect when a the source is striped + + The overall pattern is similar whatever the actual source is. This class + introduces the basic patterns. + """ + + __metaclass__ = abc.ABCMeta + + # default key used for an empty cache + emptykey = () + + _cachekeyspec = '' # used for serialization + _cachename = None # used for debug message + + @abc.abstractmethod + def __init__(self): + super(incrementalcachebase, self).__init__() + self._cachekey = None + + @util.propertycache + def _cachekeystruct(self): + # dynamic property to help subclass to change it + return struct.Struct('>' + self._cachekeyspec) + + @util.propertycache + def _cachekeysize(self): + # dynamic property to help subclass to change it + return self._cachekeystruct.size + + @abc.abstractmethod + def _updatefrom(self, repo, data): + """override this method to update you date from incrementally read data. + + Content of will depends of the sources. + """ + raise NotImplementedError + + @abc.abstractmethod + def clear(self, reset=False): + """invalidate the cache content + + if 'reset' is passed, we detected a strip and the cache will have to be + recomputed. + + Subclasses MUST overide this method to actually affect the cache data. + """ + if reset: + self._cachekey = self.emptykey if reset else None + else: + self._cachekey = None + + @abc.abstractmethod + def load(self, repo): + """Load data from disk + + Subclasses MUST restore the "cachekey" attribute while doing so. + """ + raise NotImplementedError + + @abc.abstractmethod + def _fetchupdatedata(self, repo): + """Check the source for possible changes and return necessary data + + The return is a tree elements tuple: reset, data, cachekey + + * reset: `True` when a strip is detected and cache need to be reset + * data: new data to take in account, actual type depends of the source + * cachekey: the cache key covering and precious covered data + """ + raise NotImplementedError + + @abc.abstractmethod + def _updatesummary(self, data): + """return a small string to be included in debug output""" + raise NotImplementedError + + # Useful "public" function (no need to override them) + + def update(self, repo): + """update the cache with new repository data + + The update will be incremental when possible""" + repo = repo.unfiltered() + + # If we do not have any data, try loading from disk + if self._cachekey is None: + self.load(repo) + + reset, data, newkey = self._fetchupdatedata(repo) + if newkey == self._cachekey: + return + if reset or self._cachekey is None: + repo.ui.log('cache', 'strip detected, %s cache reset\n' + % self._cachename) + self.clear(reset=True) + + starttime = timer() + self._updatefrom(repo, data) + duration = timer() - starttime + summary = self._updatesummary(data) + repo.ui.log('cache', 'updated %s in %.4f seconds (%s)\n', + self._cachename, duration, summary) + + self._cachekey = newkey + + def _serializecachekey(self): + """provide a bytes version of the cachekey""" + return self._cachekeystruct.pack(*self._cachekey) + + def _deserializecachekey(self, data): + """read the cachekey from bytes""" + return self._cachekeystruct.unpack(data) + +class changelogsourcebase(incrementalcachebase): + """an abstract class for cache sourcing data from the changelog + + For this purpose it use a cache key covering changelog content. + The cache key parts are: (tiprev, tipnode) + """ + + __metaclass__ = abc.ABCMeta + + # default key used for an empty cache + emptykey = (0, node.nullid) + _cachekeyspec = 'i20s' + _cachename = None # used for debug message + + # Useful "public" function (no need to override them) + + def _fetchchangelogdata(self, cachekey, cl): + """use a cachekey to fetch incremental data + + Exists as its own method to help subclass to reuse it.""" + tiprev = len(cl) - 1 + tipnode = cl.node(tiprev) + newkey = (tiprev, tipnode) + tiprev = len(cl) - 1 + if newkey == cachekey: + return False, [], newkey + keyrev, keynode = cachekey + if tiprev < keyrev or cl.node(keyrev) != keynode: + revs = () + if len(cl): + revs = list(cl.revs(stop=tiprev)) + return True, revs, newkey + else: + return False, list(cl.revs(start=keyrev + 1, stop=tiprev)), newkey + + def _fetchupdatedata(self, repo): + return self._fetchchangelogdata(self._cachekey, repo.changelog) + + def _updatesummary(self, data): + return '%ir' % len(data) diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/metadata.py --- a/hgext3rd/evolve/metadata.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/evolve/metadata.py Mon Dec 11 18:30:15 2017 +0100 @@ -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__ = '7.0.2.dev' +__version__ = '7.1.0.dev' testedwith = '4.1.3 4.2.3 4.3.2 4.4.1' minimumhgversion = '4.1' buglink = 'https://bz.mercurial-scm.org/' diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/obsdiscovery.py --- a/hgext3rd/evolve/obsdiscovery.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/evolve/obsdiscovery.py Mon Dec 11 18:30:15 2017 +0100 @@ -273,7 +273,7 @@ rangelength = repo.stablerange.rangelength depthrev = repo.stablerange.depthrev if opts['subranges']: - ranges = stablerange.subrangesclosure(repo, revs) + ranges = stablerange.subrangesclosure(repo, repo.stablerange, revs) else: ranges = [(r, 0) for r in revs] headers = ('rev', 'node', 'index', 'size', 'depth', 'obshash') @@ -451,6 +451,7 @@ newrevs.extend(revs) revs = newrevs + repo.depthcache.update(repo) # warm the cache for the new revs for r in revs: _obshashrange(repo, (r, 0)) diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/obshistory.py --- a/hgext3rd/evolve/obshistory.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/evolve/obshistory.py Mon Dec 11 18:30:15 2017 +0100 @@ -499,6 +499,11 @@ fm.write('date', '(%s)', fm.formatdate(date), label="evolve.date") + # initial support for showing note + if metadata.get('note'): + fm.plain('\n note: ') + fm.write('note', "%s", metadata['note'], label="evolve.note") + # Patch display if opts.get('patch'): _patchavailable = patchavailable(node, repo, marker) @@ -787,8 +792,15 @@ verb = 'split' return {'verb': verb} +# Use a more advanced version of obsfateverb that uses effect-flag +if util.safehasattr(obsutil, 'obsfateverb'): + + @eh.wrapfunction(obsutil, 'obsfateverb') + def obsfateverb(orig, *args, **kwargs): + return _successorsetverb(*args, **kwargs)['verb'] + # Hijack callers of successorsetverb -if util.safehasattr(obsutil, 'obsfateprinter'): +elif util.safehasattr(obsutil, 'obsfateprinter'): @eh.wrapfunction(obsutil, 'obsfateprinter') def obsfateprinter(orig, successors, markers, ui): diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/stablerange.py --- a/hgext3rd/evolve/stablerange.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/evolve/stablerange.py Mon Dec 11 18:30:15 2017 +0100 @@ -7,7 +7,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 collections +import abc import heapq import math import os @@ -16,8 +16,6 @@ import weakref from mercurial import ( - commands, - cmdutil, error, localrepo, node as nodemod, @@ -29,10 +27,12 @@ from mercurial.i18n import _ from . import ( + stablesort, exthelper, ) eh = exthelper.exthelper() +eh.merge(stablesort.eh) # prior to hg-4.2 there are not util.timer if util.safehasattr(util, 'timer'): @@ -44,106 +44,6 @@ else: timer = time.time -################################## -### Stable topological sorting ### -################################## -@eh.command( - 'debugstablesort', - [ - ('', 'rev', [], 'heads to start from'), - ] + commands.formatteropts, - _('')) -def debugstablesort(ui, repo, **opts): - """display the ::REVS set topologically sorted in a stable way - """ - revs = scmutil.revrange(repo, opts['rev']) - displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True) - for r in stablesort(repo, revs): - ctx = repo[r] - displayer.show(ctx) - displayer.flush(ctx) - displayer.close() - -def stablesort(repo, revs, mergecallback=None): - """return '::revs' topologically sorted in "stable" order - - This is a depth first traversal starting from 'nullrev', using node as a - tie breaker. - """ - # Various notes: - # - # * Bitbucket is used dates as tie breaker, that might be a good idea. - # - # * It seemds we can traverse in the same order from (one) head to bottom, - # if we the following record data for each merge: - # - # - highest (stablesort-wise) common ancestors, - # - order of parents (tablesort-wise) - cl = repo.changelog - parents = cl.parentrevs - nullrev = nodemod.nullrev - n = cl.node - # step 1: We need a parents -> children mapping for 2 reasons. - # - # * we build the order from nullrev to tip - # - # * we need to detect branching - children = collections.defaultdict(list) - for r in cl.ancestors(revs, inclusive=True): - p1, p2 = parents(r) - children[p1].append(r) - if p2 != nullrev: - children[p2].append(r) - # step two: walk back up - # * pick lowest node in case of branching - # * stack disregarded part of the branching - # * process merge when both parents are yielded - - # track what changeset has been - seen = [0] * (max(revs) + 2) - seen[-1] = True # nullrev is known - # starts from repository roots - # reuse the list form the mapping as we won't need it again anyway - stack = children[nullrev] - if not stack: - return [] - if 1 < len(stack): - stack.sort(key=n, reverse=True) - - # list of rev, maybe we should yield, but since we built a children mapping we are 'O(N)' already - result = [] - - current = stack.pop() - while current is not None or stack: - if current is None: - # previous iteration reached a merge or an unready merge, - current = stack.pop() - if seen[current]: - current = None - continue - p1, p2 = parents(current) - if not (seen[p1] and seen[p2]): - # we can't iterate on this merge yet because other child is not - # yielded yet (and we are topo sorting) we can discard it for now - # because it will be reached from the other child. - current = None - continue - assert not seen[current] - seen[current] = True - result.append(current) # could be yield, cf earlier comment - if mergecallback is not None and p2 != nullrev: - mergecallback(result, current) - cs = children[current] - if not cs: - current = None - elif 1 == len(cs): - current = cs[0] - else: - cs.sort(key=n, reverse=True) - current = cs.pop() # proceed on smallest - stack.extend(cs) # stack the rest for later - assert len(result) == len(set(result)) - return result ################################# ### Stable Range computation ### @@ -153,12 +53,12 @@ """return highest power of two lower than 'i'""" return 2 ** int(math.log(i - 1, 2)) -def subrangesclosure(repo, heads): +def subrangesclosure(repo, stablerange, heads): """set of all standard subrange under heads This is intended for debug purposes. Range are returned from largest to smallest in terms of number of revision it contains.""" - subranges = repo.stablerange.subranges + subranges = stablerange.subranges toproceed = [(r, 0, ) for r in heads] ranges = set(toproceed) while toproceed: @@ -169,16 +69,25 @@ toproceed.append(r) ranges = list(ranges) n = repo.changelog.node - rangelength = repo.stablerange.rangelength + rangelength = stablerange.rangelength ranges.sort(key=lambda r: (-rangelength(repo, r), n(r[0]))) return ranges +_stablerangemethodmap = { + 'branchpoint': lambda repo: repo.stablerange, + 'basic-branchpoint': lambda repo: stablerangebasic(), + 'basic-mergepoint': lambda repo: stablerangedummy_mergepoint(), + 'mergepoint': lambda repo: stablerange_mergepoint(), +} + @eh.command( 'debugstablerange', [ - ('', 'rev', [], 'operate on (rev, 0) ranges for rev in REVS'), + ('r', 'rev', [], 'operate on (rev, 0) ranges for rev in REVS'), ('', 'subranges', False, 'recursively display data for subranges too'), ('', 'verify', False, 'checks subranges content (EXPENSIVE)'), + ('', 'method', 'branchpoint', + 'method to use, one of "branchpoint", "mergepoint"') ], _('')) def debugstablerange(ui, repo, **opts): @@ -189,20 +98,8 @@ """ short = nodemod.short revs = scmutil.revrange(repo, opts['rev']) - # prewarm depth cache - unfi = repo.unfiltered() - node = unfi.changelog.node - stablerange = unfi.stablerange - depth = stablerange.depthrev - length = stablerange.rangelength - subranges = stablerange.subranges if not revs: raise error.Abort('no revisions specified') - repo.stablerange.warmup(repo, max(revs)) - if opts['subranges']: - ranges = subrangesclosure(repo, revs) - else: - ranges = [(r, 0) for r in revs] if ui.verbose: template = '%s-%d (%d, %d, %d)' @@ -222,6 +119,25 @@ short(node(rangeid[0])), rangeid[1], ) + # prewarm depth cache + unfi = repo.unfiltered() + node = unfi.changelog.node + + method = opts['method'] + getstablerange = _stablerangemethodmap.get(method) + if getstablerange is None: + raise error.Abort('unknown stable sort method: "%s"' % method) + + stablerange = getstablerange(unfi) + depth = stablerange.depthrev + length = stablerange.rangelength + subranges = stablerange.subranges + stablerange.warmup(repo, max(revs)) + + if opts['subranges']: + ranges = subrangesclosure(unfi, stablerange, revs) + else: + ranges = [(r, 0) for r in revs] for r in ranges: subs = subranges(unfi, r) @@ -241,14 +157,181 @@ else: ui.status('%s - %s\n' % (rstr, subsstr)) -class stablerange(object): +class abstractstablerange(object): + """The official API for a stablerange""" + + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def subranges(self, repo, rangeid): + """return the stable sub-ranges of a rangeid""" + raise NotImplemented() + + @abc.abstractmethod + def revsfromrange(self, repo, rangeid): + """return revision contained in a range""" + raise NotImplemented() + + @abc.abstractmethod + def depthrev(self, repo, rev): + """depth a revision""" + # Exist to allow basic implementation to ignore the depthcache + # Could be demoted to _depthrev. + raise NotImplemented() + + @abc.abstractmethod + def warmup(self, repo, upto=None): + """warmup the stable range cache""" + raise NotImplemented() + + @abc.abstractmethod + def rangelength(self, repo, rangeid): + """number of revision in """ + raise NotImplemented() + + def _slicepoint(self, repo, rangeid): + """find the standard slicing point for a range""" + rangedepth = self.depthrev(repo, rangeid[0]) + step = _hlp2(rangedepth) + standard_start = 0 + while standard_start < rangeid[1] and 0 < step: + if standard_start + step < rangedepth: + standard_start += step + step //= 2 + if rangeid[1] == standard_start: + slicesize = _hlp2(self.rangelength(repo, rangeid)) + slicepoint = rangeid[1] + slicesize + else: + assert standard_start < rangedepth + slicepoint = standard_start + return slicepoint + +class stablerangebasic(abstractstablerange): + """a very dummy implementation of stablerange + + the implementation is here to lay down the basic algorithm in the stable + range in a inefficient but easy to read manners. It should be used by test + to validate output.""" + + __metaclass__ = abc.ABCMeta + + def _sortfunction(self, repo, headrev): + return stablesort.stablesort_branchpoint(repo, [headrev]) + + def warmup(self, repo, upto=None): + # no cache to warm for basic implementation + pass + + def depthrev(self, repo, rev): + """depth a revision""" + return len(repo.revs('::%d', rev)) + + def revsfromrange(self, repo, rangeid): + """return revision contained in a range + + The range `(, )` contains all revisions stable-sorted from + , skipping the th lower revisions. + """ + headrev, index = rangeid[0], rangeid[1] + revs = self._sortfunction(repo, headrev) + return revs[index:] + + def rangelength(self, repo, rangeid): + """number of revision in """ + return len(self.revsfromrange(repo, rangeid)) + + def subranges(self, repo, rangeid): + """return the stable sub-ranges of a rangeid""" + headrev, index = rangeid[0], rangeid[1] + if self.rangelength(repo, rangeid) == 1: + return [] + slicepoint = self._slicepoint(repo, rangeid) + + # search for range defining the lower set of revision + # + # we walk the lower set from the top following the stable order of the + # current "head" of the lower range. + # + # As soon as the revision in the lowerset diverges from the one in the + # range being generated, we emit the range and start a new one. + result = [] + lowerrevs = self.revsfromrange(repo, rangeid)[:(slicepoint - index)] + head = None + headrange = None + skip = None + for rev in lowerrevs[::-1]: + if head is None: + head = rev + headrange = self.revsfromrange(repo, (head, 0)) + skip = self.depthrev(repo, rev) - 1 + elif rev != headrange[skip - 1]: + result.append((head, skip)) + head = rev + headrange = self.revsfromrange(repo, (head, 0)) + skip = self.depthrev(repo, rev) - 1 + else: + skip -= 1 + result.append((head, skip)) + + result.reverse() + + # top part is trivial + top = (headrev, slicepoint) + result.append(top) + + # double check the result + initialrevs = self.revsfromrange(repo, rangeid) + subrangerevs = sum((self.revsfromrange(repo, sub) for sub in result), + []) + assert initialrevs == subrangerevs + return result + +class stablerangedummy_mergepoint(stablerangebasic): + """a very dummy implementation of stablerange use 'mergepoint' sorting + """ + + def _sortfunction(self, repo, headrev): + return stablesort.stablesort_mergepoint_head_basic(repo, [headrev]) + +class stablerangecached(abstractstablerange): + """an implementation of stablerange using caching""" + + __metaclass__ = abc.ABCMeta + + def depthrev(self, repo, rev): + return repo.depthcache.get(rev) + + def rangelength(self, repo, rangeid): + """number of revision in """ + headrev, index = rangeid[0], rangeid[1] + return self.depthrev(repo, headrev) - index + +class stablerange_mergepoint(stablerangecached, stablerangebasic): + """Stablerange implementation using 'mergepoint' based sorting + """ + + def __init__(self): + self._sortcache = stablesort.stablesortcache() + super(stablerange_mergepoint, self).__init__() + + def _sortfunction(self, repo, headrev): + return self._sortcache.get(repo, headrev) + + def revsfromrange(self, repo, rangeid): + """return revision contained in a range + + The range `(, )` contains all revisions stable-sorted from + , skipping the th lower revisions. + """ + limit = self.rangelength(repo, rangeid) + return self._sortcache.get(repo, rangeid[0], limit=limit) + +class stablerange(stablerangecached): def __init__(self, lrusize=2000): # The point up to which we have data in cache self._tiprev = None self._tipnode = None - # cache the 'depth' of a changeset, the size of '::rev' - self._depthcache = {} # cache the standard stable subranges or a range self._subrangescache = {} # To slices merge, we need to walk their descendant in reverse stable @@ -271,6 +354,7 @@ def warmup(self, repo, upto=None): """warm the cache up""" repo = repo.unfiltered() + repo.depthcache.update(repo) cl = repo.changelog # subrange should be warmed from head to range to be able to benefit # from revsfromrange cache. otherwise each merge will trigger its own @@ -337,44 +421,6 @@ repo.ui.log('evoext-cache', 'updated stablerange cache in %.4f seconds\n', duration) - def depthrev(self, repo, rev): - repo = repo.unfiltered() - cl = repo.changelog - depth = self._getdepth - nullrev = nodemod.nullrev - stack = [rev] - while stack: - revdepth = None - current = stack[-1] - revdepth = depth(current) - if revdepth is not None: - stack.pop() - continue - p1, p2 = self._parents(current, cl.parentrevs) - if p1 == nullrev: - # root case - revdepth = 1 - elif p2 == nullrev: - # linear commit case - parentdepth = depth(p1) - if parentdepth is None: - stack.append(p1) - else: - revdepth = parentdepth + 1 - else: - # merge case - revdepth = self._depthmerge(cl, current, p1, p2, stack) - if revdepth is not None: - self._setdepth(current, revdepth) - stack.pop() - # actual_depth = len(list(cl.ancestors([rev], inclusive=True))) - # assert revdepth == actual_depth, (rev, revdepth, actual_depth) - return revdepth - - def rangelength(self, repo, rangeid): - headrev, index = rangeid[0], rangeid[1] - return self.depthrev(repo, headrev) - index - def subranges(self, repo, rangeid): cached = self._getsub(rangeid) if cached is not None: @@ -399,8 +445,9 @@ if allrevs is None: allrevs = self._getrevsfrommerge(repo, headrev) if allrevs is None: - allrevs = stablesort(repo, [headrev], - mergecallback=self._filestablesortcache) + mc = self._filestablesortcache + sorting = stablesort.stablesort_branchpoint + allrevs = sorting(repo, [headrev], mergecallback=mc) self._stablesortcache[headrev] = allrevs # takes from index revs = allrevs[index:] @@ -415,18 +462,6 @@ self._parentscache[rev] = parents return parents - def _getdepth(self, rev): - """utility function used to access the depth cache - - This mostly exist to help the on disk persistence.""" - return self._depthcache.get(rev) - - def _setdepth(self, rev, value): - """utility function used to set the depth cache - - This mostly exist to help the on disk persistence.""" - self._depthcache[rev] = value - def _getsub(self, rev): """utility function used to access the subranges cache @@ -489,63 +524,18 @@ expected = len(revs) - 1 # Since we do warmup properly, we can expect the cache to be hot # for everythin under the merge we investigate - cache = self._depthcache + cache = repo.depthcache # note: we cannot do a binary search because element under the # inherited point might have mismatching depth because of inner # branching. for rev in i: - if cache[rev] == expected: + if cache.get(rev) == expected: break expected -= 1 value = (expected - 1, rev) self._inheritancecache[merge] = value return value - def _depthmerge(self, cl, rev, p1, p2, stack): - # sub method to simplify the main 'depthrev' one - revdepth = None - depth = self._getdepth - depth_p1 = depth(p1) - depth_p2 = depth(p2) - missingparent = False - if depth_p1 is None: - stack.append(p1) - missingparent = True - if depth_p2 is None: - stack.append(p2) - missingparent = True - if missingparent: - return None - # computin depth of a merge - # XXX the common ancestors heads could be cached - ancnodes = cl.commonancestorsheads(cl.node(p1), cl.node(p2)) - ancrevs = [cl.rev(a) for a in ancnodes] - anyunkown = False - ancdepth = [] - for r in ancrevs: - d = depth(r) - if d is None: - anyunkown = True - stack.append(r) - ancdepth.append((r, d)) - if anyunkown: - return None - if not ancrevs: - # unrelated branch, (no common root) - revdepth = depth_p1 + depth_p2 + 1 - elif len(ancrevs) == 1: - # one unique branch point: - # we can compute depth without any walk - depth_anc = ancdepth[0][1] - revdepth = depth_p1 + (depth_p2 - depth_anc) + 1 - else: - # multiple ancestors, we pick one that is - # * the deepest (less changeset outside of it), - # * lowest revs because more chance to have descendant of other "above" - anc, revdepth = max(ancdepth, key=lambda x: (x[1], -x[0])) - revdepth += len(cl.findmissingrevs(common=[anc], heads=[rev])) - return revdepth - def _subranges(self, repo, rangeid): if self.rangelength(repo, rangeid) == 1: return [] @@ -592,22 +582,6 @@ # look like we found a relevent parentrange with no cache yet return reurange - def _slicepoint(self, repo, rangeid): - rangedepth = self.depthrev(repo, rangeid[0]) - step = _hlp2(rangedepth) - standard_start = 0 - while standard_start < rangeid[1] and 0 < step: - if standard_start + step < rangedepth: - standard_start += step - step //= 2 - if rangeid[1] == standard_start: - slicesize = _hlp2(self.rangelength(repo, rangeid)) - slicepoint = rangeid[1] + slicesize - else: - assert standard_start < rangedepth - slicepoint = standard_start - return slicepoint - def _slicesrangeat(self, repo, rangeid, globalindex): p1, p2 = self._parents(rangeid[0], repo.changelog.parentrevs) if p2 == nodemod.nullrev: @@ -635,7 +609,6 @@ def _slicesrangeatmerge(self, repo, rangeid, globalindex): localindex = globalindex - rangeid[1] - cl = repo.changelog result = [] allrevs = self.revsfromrange(repo, rangeid) @@ -646,49 +619,24 @@ # revision we needs result.append((bottomrevs[-1], rangeid[1])) else: - parentrevs = cl.parentrevs - parents = self._parents - bheads = set(bottomrevs) - du = bheads.difference_update - reachableroots = repo.changelog.reachableroots - minrev = min(bottomrevs) - for r in bottomrevs: - du(parents(r, parentrevs)) - for h in bheads: - # reachable roots is fast because is C - # - # It is worth noting that will use this kind of filtering from - # "h" multiple time in a warming run. So using "ancestors" and - # caching that should be faster. But python code filtering on - # the ancestors end up being slower. - hrevs = reachableroots(minrev, [h], bottomrevs, True) - start = self.depthrev(repo, h) - len(hrevs) - entry = (h, start) - result.append(entry) + head = None + headrange = None + skip = None + for rev in bottomrevs[::-1]: + if head is None: + head = rev + headrange = self.revsfromrange(repo, (head, 0)) + skip = self.depthrev(repo, rev) - 1 + elif rev != headrange[skip - 1]: + result.append((head, skip)) + head = rev + headrange = self.revsfromrange(repo, (head, 0)) + skip = self.depthrev(repo, rev) - 1 + else: + skip -= 1 + result.append((head, skip)) - # Talking about python code being slow, the following code is an - # alternative implementation. - # - # It complexity is better since is does a single traversal on the - # bottomset. However since it is all python it end up being - # slower. - # I'm keeping it here as an inspiration for a future C version - # branches = [] - # for current in reversed(bottomrevs): - # ps = parents(current, parentrevs) - # found = False - # for brevs, bexpect in branches: - # if current in bexpect: - # found = True - # brevs.append(current) - # bexpect.discard(current) - # bexpect.update(ps) - # if not found: - # branches.append(([current], set(ps))) - # for revs, __ in reversed(branches): - # head = revs[0] - # index = self.depthrev(repo, head) - len(revs) - # result.append((head, index)) + result.reverse() # top part is trivial top = (rangeid[0], globalindex) @@ -704,7 +652,6 @@ tiprev INTEGER NOT NULL, tipnode BLOB NOT NULL );""", - "CREATE TABLE depth(rev INTEGER NOT NULL PRIMARY KEY, depth INTEGER NOT NULL);", """CREATE TABLE range(rev INTEGER NOT NULL, idx INTEGER NOT NULL, PRIMARY KEY(rev, idx));""", @@ -719,19 +666,15 @@ );""", "CREATE INDEX subranges_index ON subranges (suprev, supidx);", "CREATE INDEX range_index ON range (rev, idx);", - "CREATE INDEX depth_index ON depth (rev);" ] _newmeta = "INSERT INTO meta (schemaversion, tiprev, tipnode) VALUES (?,?,?);" _updatemeta = "UPDATE meta SET tiprev = ?, tipnode = ?;" -_updatedepth = "INSERT INTO depth(rev, depth) VALUES (?,?);" _updaterange = "INSERT INTO range(rev, idx) VALUES (?,?);" _updatesubranges = """INSERT INTO subranges(listidx, suprev, supidx, subrev, subidx) VALUES (?,?,?,?,?);""" _queryexist = "SELECT name FROM sqlite_master WHERE type='table' AND name='meta';" _querymeta = "SELECT schemaversion, tiprev, tipnode FROM meta;" -_querydepth = "SELECT depth FROM depth WHERE rev = ?;" -_batchdepth = "SELECT rev, depth FROM depth;" _queryrange = "SELECT * FROM range WHERE (rev = ? AND idx = ?);" _querysubranges = """SELECT subrev, subidx FROM subranges @@ -740,20 +683,18 @@ class sqlstablerange(stablerange): - _schemaversion = 0 + _schemaversion = 1 def __init__(self, repo): lrusize = repo.ui.configint('experimental', 'obshashrange.lru-size', 2000) super(sqlstablerange, self).__init__(lrusize=lrusize) self._vfs = repo.vfs - self._path = repo.vfs.join('cache/evoext_stablerange_v0.sqlite') + self._path = repo.vfs.join('cache/evoext_stablerange_v1.sqlite') self._cl = repo.unfiltered().changelog # (okay to keep an old one) self._ondisktiprev = None self._ondisktipnode = None - self._unsaveddepth = {} self._unsavedsubranges = {} - self._fulldepth = False def warmup(self, repo, upto=None): self._con # make sure the data base is loaded @@ -774,22 +715,6 @@ repo.ui.warn('(cache will not be saved)\n') super(sqlstablerange, self).warmup(repo, upto) - def _getdepth(self, rev): - cache = self._depthcache - if rev not in cache and rev <= self._ondisktiprev and self._con is not None: - value = None - result = self._con.execute(_querydepth, (rev,)).fetchone() - if result is not None: - value = result[0] - # in memory caching of the value - cache[rev] = value - return cache.get(rev) - - def _setdepth(self, rev, depth): - assert rev not in self._unsaveddepth - self._unsaveddepth[rev] = depth - super(sqlstablerange, self)._setdepth(rev, depth) - def _getsub(self, rangeid): cache = self._subrangescache if rangeid not in cache and rangeid[0] <= self._ondisktiprev and self._con is not None: @@ -806,10 +731,6 @@ self._unsavedsubranges[rangeid] = value super(sqlstablerange, self)._setsub(rangeid, value) - def _inheritancepoint(self, *args, **kwargs): - self._loaddepth() - return super(sqlstablerange, self)._inheritancepoint(*args, **kwargs) - def _db(self): try: util.makedirs(self._vfs.dirname(self._path)) @@ -845,7 +766,8 @@ def _save(self, repo): repo = repo.unfiltered() - if not (self._unsavedsubranges or self._unsaveddepth): + repo.depthcache.save(repo) + if not self._unsavedsubranges: return # no new data if self._con is None: @@ -884,26 +806,12 @@ ] con.execute(_updatemeta, meta) - self._savedepth(con, repo) self._saverange(con, repo) con.commit() self._ondisktiprev = self._tiprev self._ondisktipnode = self._tipnode - self._unsaveddepth.clear() self._unsavedsubranges.clear() - def _savedepth(self, con, repo): - repo = repo.unfiltered() - data = self._unsaveddepth.items() - con.executemany(_updatedepth, data) - - def _loaddepth(self): - """batch load all data about depth""" - if not (self._fulldepth or self._con is None): - result = self._con.execute(_batchdepth) - self._depthcache.update(result.fetchall()) - self._fulldepth = True - def _saverange(self, con, repo): repo = repo.unfiltered() data = [] diff -r 875de4816c5b -r bd99cb54712b hgext3rd/evolve/stablesort.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/evolve/stablesort.py Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,395 @@ +# Code dedicated to the computation of stable sorting +# +# These stable sorting are used stable ranges +# +# Copyright 2017 Pierre-Yves David +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +import collections + +from mercurial import ( + commands, + cmdutil, + error, + node as nodemod, + scmutil, +) + +from mercurial.i18n import _ + +from . import ( + depthcache, + exthelper, +) + +eh = exthelper.exthelper() +eh.merge(depthcache.eh) + +def _mergepoint_tie_breaker(repo): + """the key use to tie break merge parent + + Exists as a function to help playing with different approaches. + + Possible other factor are: + * depth of node, + * number of exclusive merges, + * number of jump points. + * + """ + return repo.changelog.node + +@eh.command( + 'debugstablesort', + [ + ('r', 'rev', [], 'heads to start from'), + ('', 'method', 'branchpoint', "method used for sorting, one of: " + "branchpoint, basic-mergepoint and basic-headstart"), + ('l', 'limit', '', 'number of revision display (default to all)') + ] + commands.formatteropts, + _('')) +def debugstablesort(ui, repo, **opts): + """display the ::REVS set topologically sorted in a stable way + """ + revs = scmutil.revrange(repo, opts['rev']) + + method = opts['method'] + sorting = _methodmap.get(method) + if sorting is None: + valid_method = ', '.join(sorted(_methodmap)) + raise error.Abort('unknown sorting method: "%s"' % method, + hint='pick one of: %s' % valid_method) + + displayer = cmdutil.show_changeset(ui, repo, opts, buffered=True) + kwargs = {} + if opts['limit']: + kwargs['limit'] = int(opts['limit']) + for r in sorting(repo, revs, **kwargs): + ctx = repo[r] + displayer.show(ctx) + displayer.flush(ctx) + displayer.close() + +def stablesort_branchpoint(repo, revs, mergecallback=None): + """return '::revs' topologically sorted in "stable" order + + This is a depth first traversal starting from 'nullrev', using node as a + tie breaker. + """ + # Various notes: + # + # * Bitbucket is used dates as tie breaker, that might be a good idea. + # + # * It seemds we can traverse in the same order from (one) head to bottom, + # if we the following record data for each merge: + # + # - highest (stablesort-wise) common ancestors, + # - order of parents (tablesort-wise) + cl = repo.changelog + parents = cl.parentrevs + nullrev = nodemod.nullrev + n = cl.node + # step 1: We need a parents -> children mapping for 2 reasons. + # + # * we build the order from nullrev to tip + # + # * we need to detect branching + children = collections.defaultdict(list) + for r in cl.ancestors(revs, inclusive=True): + p1, p2 = parents(r) + children[p1].append(r) + if p2 != nullrev: + children[p2].append(r) + # step two: walk back up + # * pick lowest node in case of branching + # * stack disregarded part of the branching + # * process merge when both parents are yielded + + # track what changeset has been + seen = [0] * (max(revs) + 2) + seen[-1] = True # nullrev is known + # starts from repository roots + # reuse the list form the mapping as we won't need it again anyway + stack = children[nullrev] + if not stack: + return [] + if 1 < len(stack): + stack.sort(key=n, reverse=True) + + # list of rev, maybe we should yield, but since we built a children mapping we are 'O(N)' already + result = [] + + current = stack.pop() + while current is not None or stack: + if current is None: + # previous iteration reached a merge or an unready merge, + current = stack.pop() + if seen[current]: + current = None + continue + p1, p2 = parents(current) + if not (seen[p1] and seen[p2]): + # we can't iterate on this merge yet because other child is not + # yielded yet (and we are topo sorting) we can discard it for now + # because it will be reached from the other child. + current = None + continue + assert not seen[current] + seen[current] = True + result.append(current) # could be yield, cf earlier comment + if mergecallback is not None and p2 != nullrev: + mergecallback(result, current) + cs = children[current] + if not cs: + current = None + elif 1 == len(cs): + current = cs[0] + else: + cs.sort(key=n, reverse=True) + current = cs.pop() # proceed on smallest + stack.extend(cs) # stack the rest for later + assert len(result) == len(set(result)) + return result + +def stablesort_mergepoint_multirevs(repo, revs): + """return '::revs' topologically sorted in "stable" order + + This is a depth first traversal starting from 'revs' (toward root), using node as a + tie breaker. + """ + cl = repo.changelog + tiebreaker = _mergepoint_tie_breaker(repo) + if not revs: + return [] + elif len(revs) == 1: + heads = list(revs) + else: + # keeps heads only + heads = sorted(repo.revs('heads(%ld::%ld)', revs, revs), key=tiebreaker) + + results = [] + while heads: + h = heads.pop() + if revs: + bound = cl.findmissingrevs(common=heads, heads=[h]) + else: + bound = cl.ancestors([h], inclusive=True) + results.append(stablesort_mergepoint_bounded(repo, h, bound)) + if len(results) == 1: + return results[0] + finalresults = [] + for r in results[::-1]: + finalresults.extend(r) + return finalresults + +def stablesort_mergepoint_bounded(repo, head, revs): + """return 'revs' topologically sorted in "stable" order. + + The 'revs' set MUST have 'head' as its one and unique head. + """ + # Various notes: + # + # * Bitbucket is using dates as tie breaker, that might be a good idea. + cl = repo.changelog + parents = cl.parentrevs + nullrev = nodemod.nullrev + tiebreaker = _mergepoint_tie_breaker(repo) + # step 1: We need a parents -> children mapping to detect dependencies + children = collections.defaultdict(set) + parentmap = {} + for r in revs: + p1, p2 = parents(r) + children[p1].add(r) + if p2 != nullrev: + children[p2].add(r) + parentmap[r] = tuple(sorted((p1, p2), key=tiebreaker)) + elif p1 != nullrev: + parentmap[r] = (p1,) + else: + parentmap[r] = () + # step two: walk again, + stack = [head] + resultset = set() + result = [] + + def add(current): + resultset.add(current) + result.append(current) + + while stack: + current = stack.pop() + add(current) + parents = parentmap[current] + for p in parents: + if 1 < len(children[p]) and not children[p].issubset(resultset): + # we need other children to be yield first + continue + if p in revs: + stack.append(p) + + result.reverse() + assert len(result) == len(resultset) + return result + +def stablesort_mergepoint_head_basic(repo, revs, limit=None): + heads = repo.revs('heads(%ld)', revs) + if not heads: + return [] + elif 2 < len(heads): + raise error.Abort('cannot use head based merging, %d heads found' + % len(heads)) + head = heads.first() + revs = stablesort_mergepoint_bounded(repo, head, repo.revs('::%d', head)) + if limit is None: + return revs + return revs[-limit:] + +def stablesort_mergepoint_head_debug(repo, revs, limit=None): + heads = repo.revs('heads(%ld)', revs) + if not heads: + return [] + elif 2 < len(heads): + raise error.Abort('cannot use head based merging, %d heads found' + % len(heads)) + head = heads.first() + revs = stablesort_mergepoint_head(repo, head) + if limit is None: + return revs + return revs[-limit:] + +def stablesort_mergepoint_head(repo, head): + """return '::rev' topologically sorted in "stable" order + + This is a depth first traversal starting from 'rev' (toward root), using node as a + tie breaker. + """ + cl = repo.changelog + parents = cl.parentrevs + tiebreaker = _mergepoint_tie_breaker(repo) + + top = [head] + mid = [] + bottom = [] + + ps = [p for p in parents(head) if p is not nodemod.nullrev] + while len(ps) == 1: + top.append(ps[0]) + ps = [p for p in parents(ps[0]) if p is not nodemod.nullrev] + top.reverse() + if len(ps) == 2: + ps.sort(key=tiebreaker) + + # get the part from the highest parent. This is the part that changes + mid_revs = repo.revs('only(%d, %d)', ps[1], ps[0]) + if mid_revs: + mid = stablesort_mergepoint_bounded(repo, ps[1], mid_revs) + + # And follow up with part othe parent we can inherit from + bottom_revs = cl.ancestors([ps[0]], inclusive=True) + bottom = stablesort_mergepoint_bounded(repo, ps[0], bottom_revs) + + return bottom + mid + top + +def stablesort_mergepoint_head_cached(repo, revs, limit=None): + heads = repo.revs('heads(%ld)', revs) + if not heads: + return [] + elif 2 < len(heads): + raise error.Abort('cannot use head based merging, %d heads found' + % len(heads)) + head = heads.first() + cache = stablesortcache() + return cache.get(repo, head, limit=limit) + +class stablesortcache(object): + + def get(self, repo, rev, limit=None): + result = [] + for r in self._revsfrom(repo, rev): + result.append(r) + if limit is not None and limit <= len(result): + break + result.reverse() + return result + + def _revsfrom(self, repo, head): + tiebreaker = _mergepoint_tie_breaker(repo) + cl = repo.changelog + parentsfunc = cl.parentrevs + + def parents(rev): + return [p for p in parentsfunc(rev) if p is not nodemod.nullrev] + + current = head + previous_current = None + + while current is not None: + assert current is not previous_current + yield current + previous_current = current + + ps = parents(current) + if not ps: + current = None # break + if len(ps) == 1: + current = ps[0] + elif len(ps) == 2: + lower_parent, higher_parent = sorted(ps, key=tiebreaker) + + for rev in self._process_exclusive_side(lower_parent, + higher_parent, + cl.findmissingrevs, + parents, + tiebreaker): + yield rev + + current = lower_parent + + def _process_exclusive_side(self, lower, higher, findmissingrevs, parents, tiebreaker): + + exclusive = findmissingrevs(common=[lower], + heads=[higher]) + + stack = [] + seen = set() + children = collections.defaultdict(set) + if not exclusive: + current = None + else: + current = higher + bound = set(exclusive) + for r in exclusive: + for p in parents(r): + children[p].add(r) + + previous_current = None + while current is not None: + assert current is not previous_current + yield current + seen.add(current) + previous_current = current + + ps = parents(current) + + usable_parents = [p for p in ps + if (p in bound and children[p].issubset(seen))] + if not usable_parents: + if stack: + current = stack.pop() + else: + current = None + elif len(usable_parents) == 1: + current = usable_parents[0] + else: + lower_parent, higher_parent = sorted(usable_parents, key=tiebreaker) + stack.append(lower_parent) + current = higher_parent + +_methodmap = { + 'branchpoint': stablesort_branchpoint, + 'basic-mergepoint': stablesort_mergepoint_multirevs, + 'basic-headstart': stablesort_mergepoint_head_basic, + 'headstart': stablesort_mergepoint_head_debug, + 'headcached': stablesort_mergepoint_head_cached, +} diff -r 875de4816c5b -r bd99cb54712b hgext3rd/serverminitopic.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hgext3rd/serverminitopic.py Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,226 @@ +"""enable a minimal verison of topic for server + +Non publishing repository will see topic as "branch:topic" in the branch field. + +In addition to adding the extensions, the feature must be manually enabled in the config: + + [experimental] + server-mini-topic = yes +""" +import hashlib +import contextlib + +from mercurial import ( + branchmap, + context, + encoding, + extensions, + node, + registrar, + util, + wireproto, +) + +if util.safehasattr(registrar, 'configitem'): + + configtable = {} + configitem = registrar.configitem(configtable) + configitem('experimental', 'server-mini-topic', + default=False, + ) + +def hasminitopic(repo): + """true if minitopic is enabled on the repository + + (The value is cached on the repository) + """ + enabled = getattr(repo, '_hasminitopic', None) + if enabled is None: + enabled = (repo.ui.configbool('experimental', 'server-mini-topic') + and not repo.publishing()) + repo._hasminitopic = enabled + return enabled + +### make topic visible though "ctx.branch()" + +class topicchangectx(context.changectx): + """a sunclass of changectx that add topic to the branch name""" + + def branch(self): + branch = super(topicchangectx, self).branch() + if hasminitopic(self._repo) and self.phase(): + topic = self._changeset.extra.get('topic') + if topic is not None: + topic = encoding.tolocal(topic) + branch = '%s:%s' % (branch, topic) + return branch + +### avoid caching topic data in rev-branch-cache + +class revbranchcacheoverlay(object): + """revbranch mixin that don't use the cache for non public changeset""" + + def _init__(self, *args, **kwargs): + super(revbranchcacheoverlay, self).__init__(*args, **kwargs) + if 'branchinfo' in vars(self): + del self.branchinfo + + def branchinfo(self, rev): + """return branch name and close flag for rev, using and updating + persistent cache.""" + phase = self._repo._phasecache.phase(self, rev) + if phase: + ctx = self._repo[rev] + return ctx.branch(), ctx.closesbranch() + return super(revbranchcacheoverlay, self).branchinfo(rev) + +def reposetup(ui, repo): + """install a repo class with a special revbranchcache""" + + if hasminitopic(repo): + repo = repo.unfiltered() + + class minitopicrepo(repo.__class__): + """repository subclass that install the modified cache""" + + def revbranchcache(self): + if self._revbranchcache is None: + cache = super(minitopicrepo, self).revbranchcache() + + class topicawarerbc(revbranchcacheoverlay, cache.__class__): + pass + cache.__class__ = topicawarerbc + if 'branchinfo' in vars(cache): + del cache.branchinfo + self._revbranchcache = cache + return self._revbranchcache + + repo.__class__ = minitopicrepo + +### topic aware branch head cache + +def _phaseshash(repo, maxrev): + """uniq ID for a phase matching a set of rev""" + revs = set() + cl = repo.changelog + fr = cl.filteredrevs + nm = cl.nodemap + for roots in repo._phasecache.phaseroots[1:]: + for n in roots: + r = nm.get(n) + if r not in fr and r < maxrev: + revs.add(r) + key = node.nullid + revs = sorted(revs) + if revs: + s = hashlib.sha1() + for rev in revs: + s.update('%s;' % rev) + key = s.digest() + return key + +# needed to prevent reference used for 'super()' call using in branchmap.py to +# no go into cycle. (yes, URG) +_oldbranchmap = branchmap.branchcache + +@contextlib.contextmanager +def oldbranchmap(): + previous = branchmap.branchcache + try: + branchmap.branchcache = _oldbranchmap + yield + finally: + branchmap.branchcache = previous + +_publiconly = set([ + 'base', + 'immutable', +]) + +def mighttopic(repo): + return hasminitopic(repo) and repo.filtername not in _publiconly + +class _topiccache(branchmap.branchcache): # combine me with branchmap.branchcache + + def __init__(self, *args, **kwargs): + # super() call may fail otherwise + with oldbranchmap(): + super(_topiccache, self).__init__(*args, **kwargs) + self.phaseshash = None + + def copy(self): + """return an deep copy of the branchcache object""" + new = self.__class__(self, self.tipnode, self.tiprev, self.filteredhash, + self._closednodes) + new.phaseshash = self.phaseshash + return new + + def validfor(self, repo): + """Is the cache content valid regarding a repo + + - False when cached tipnode is unknown or if we detect a strip. + - True when cache is up to date or a subset of current repo.""" + valid = super(_topiccache, self).validfor(repo) + if not valid: + return False + elif not mighttopic(repo) and self.phaseshash is None: + # phasehash at None means this is a branchmap + # coming from a public only set + return True + else: + try: + valid = self.phaseshash == _phaseshash(repo, self.tiprev) + return valid + except IndexError: + return False + + def write(self, repo): + # we expect (hope) mutable set to be small enough to be that computing + # it all the time will be fast enough + if not mighttopic(repo): + super(_topiccache, self).write(repo) + + def update(self, repo, revgen): + """Given a branchhead cache, self, that may have extra nodes or be + missing heads, and a generator of nodes that are strictly a superset of + heads missing, this function updates self to be correct. + """ + super(_topiccache, self).update(repo, revgen) + if mighttopic(repo): + self.phaseshash = _phaseshash(repo, self.tiprev) + +def wrapread(orig, repo): + # Avoiding to write cache for filter where topic applies is a good step, + # but we need to also avoid reading it. Existing branchmap cache might + # exists before the turned the feature on. + if mighttopic(repo): + return None + return orig(repo) + +# advertise topic capabilities + +def wireprotocaps(orig, repo, proto): + caps = orig(repo, proto) + if hasminitopic(repo): + caps.append('topics') + return caps + +# wrap the necessary bit + +def wrapclass(container, oldname, new): + old = getattr(container, oldname) + if not issubclass(old, new): + targetclass = new + # check if someone else already wrapped the class and handle that + if not issubclass(new, old): + class targetclass(new, old): + pass + setattr(container, oldname, targetclass) + current = getattr(container, oldname) + assert issubclass(current, new), (current, new, targetclass) + +def uisetup(ui): + wrapclass(context, 'changectx', topicchangectx) + wrapclass(branchmap, 'branchcache', _topiccache) + extensions.wrapfunction(branchmap, 'read', wrapread) + extensions.wrapfunction(wireproto, '_capabilities', wireprotocaps) diff -r 875de4816c5b -r bd99cb54712b hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/topic/__init__.py Mon Dec 11 18:30:15 2017 +0100 @@ -174,13 +174,16 @@ 'topic.active': 'green', } -__version__ = '0.5.2.dev' +__version__ = '0.6.0.dev' testedwith = '4.1.3 4.2.3 4.3.3 4.4.1' minimumhgversion = '4.1' buglink = 'https://bz.mercurial-scm.org/' if util.safehasattr(registrar, 'configitem'): + + from mercurial import configitems + configtable = {} configitem = registrar.configitem(configtable) @@ -199,6 +202,9 @@ configitem('_internal', 'keep-topic', default=False, ) + configitem('experimental', 'topic-mode.server', + default=configitems.dynamicdefault, + ) def extsetup(ui): # register config that strictly belong to other code (thg, core, etc) @@ -223,6 +229,7 @@ return '' return self.extra().get(constants.extrakey, '') context.basectx.topic = _contexttopic + def _contexttopicidx(self): topic = self.topic() if not topic: @@ -318,6 +325,10 @@ cmdutil.summaryhooks.add('topic', summaryhook) + # Wrap workingctx extra to return the topic name + extensions.wrapfunction(context.workingctx, '__init__', wrapinit) + # Wrap changelog.add to drop empty topic + extensions.wrapfunction(changelog.changelog, 'add', wrapadd) def reposetup(ui, repo): if not isinstance(repo, localrepo.localrepository): @@ -421,7 +432,19 @@ origvalidator(tr2) tr.validator = validator - if (repo.ui.configbool('experimental', 'topic.publish-bare-branch') + topicmodeserver = repo.ui.config('experimental', + 'topic-mode.server', 'ignore') + ispush = (desc.startswith('push') or desc.startswith('serve')) + if (topicmodeserver != 'ignore' and ispush): + origvalidator = tr.validator + + def validator(tr2): + repo = reporef() + flow.rejectuntopicedchangeset(repo, tr2) + return origvalidator(tr2) + tr.validator = validator + + elif (repo.ui.configbool('experimental', 'topic.publish-bare-branch') and (desc.startswith('push') or desc.startswith('serve')) ): @@ -467,10 +490,6 @@ repo.names.addnamespace(namespaces.namespace( 'topics', 'topic', namemap=_namemap, nodemap=_nodemap, listnames=lambda repo: repo.topics)) - # Wrap workingctx extra to return the topic name - extensions.wrapfunction(context.workingctx, '__init__', wrapinit) - # Wrap changelog.add to drop empty topic - extensions.wrapfunction(changelog.changelog, 'add', wrapadd) def wrapinit(orig, self, repo, *args, **kwargs): orig(self, repo, *args, **kwargs) diff -r 875de4816c5b -r bd99cb54712b hgext3rd/topic/flow.py --- a/hgext3rd/topic/flow.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/topic/flow.py Mon Dec 11 18:30:15 2017 +0100 @@ -30,6 +30,32 @@ nodes = [cl.node(r) for r in topublish] repo._phasecache.advanceboundary(repo, tr, phases.public, nodes) +def rejectuntopicedchangeset(repo, tr): + """Reject the push if there are changeset without topic""" + if 'node' not in tr.hookargs: # no new revs + return + + startnode = node.bin(tr.hookargs['node']) + + mode = repo.ui.config('experimental', 'topic-mode.server', 'ignore') + + untopiced = repo.revs('not public() and (%n:) - hidden() - topic()', startnode) + if untopiced: + num = len(untopiced) + fnode = repo[untopiced.first()].hex()[:10] + if num == 1: + msg = _("%s") % fnode + else: + msg = _("%s and %d more") % (fnode, num - 1) + if mode == 'warning': + fullmsg = _("pushed draft changeset without topic: %s\n") + repo.ui.warn(fullmsg % msg) + elif mode == 'enforce': + fullmsg = _("rejecting draft changesets: %s") + raise error.Abort(fullmsg % msg) + else: + repo.ui.warn(_("unknown 'topic-mode.server': %s\n" % mode)) + def wrappush(orig, repo, remote, *args, **kwargs): """interpret the --publish flag and pass it to the push operation""" newargs = kwargs.copy() diff -r 875de4816c5b -r bd99cb54712b hgext3rd/topic/stack.py --- a/hgext3rd/topic/stack.py Mon Dec 11 09:33:32 2017 +0100 +++ b/hgext3rd/topic/stack.py Mon Dec 11 18:30:15 2017 +0100 @@ -12,7 +12,11 @@ obsolete, util, ) -from .evolvebits import builddependencies, _singlesuccessor +from .evolvebits import ( + _singlesuccessor, + MultipleSuccessorsError, + builddependencies, +) short = node.short @@ -285,7 +289,15 @@ p1 = ctx.p1() p2 = ctx.p2() if p1.obsolete(): - p1 = repo[_singlesuccessor(repo, p1)] + try: + p1 = repo[_singlesuccessor(repo, p1)] + except MultipleSuccessorsError as e: + successors = e.successorssets + if len(successors) > 1: + # case of divergence which we don't handle yet + raise + p1 = repo[successors[0][-1]] + if p2.node() != node.nullid: entries.append((idxmap.get(p1.rev()), False, p1)) entries.append((idxmap.get(p2.rev()), False, p2)) diff -r 875de4816c5b -r bd99cb54712b setup.py --- a/setup.py Mon Dec 11 09:33:32 2017 +0100 +++ b/setup.py Mon Dec 11 18:30:15 2017 +0100 @@ -19,6 +19,7 @@ return get_metadata()['minimumhgversion'] py_modules = [ + 'hgext3rd.serverminitopic', ] py_packages = [ 'hgext3rd', diff -r 875de4816c5b -r bd99cb54712b tests/test-amend.t --- a/tests/test-amend.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-amend.t Mon Dec 11 18:30:15 2017 +0100 @@ -18,10 +18,18 @@ $ hg branch foo marked working directory as branch foo (branches are permanent and global, did you want a bookmark?) - $ hg amend -d '0 0' + $ hg amend -d '0 0' -n "this a note on the obsmarker and supported for hg>=4.4" + current hg version does not support storing note in obsmarker $ hg debugobsolete 07f4944404050f47db2e5c5071e0e84e7a27bba9 6a022cbb61d5ba0f03f98ff2d36319dfea1034ae 0 (*) {'ef1': '*', 'user': 'test'} (glob) b2e32ffb533cbe1d5759638c0cd4e8abc43b2738 0 {07f4944404050f47db2e5c5071e0e84e7a27bba9} (*) {'ef1': '*', 'user': 'test'} (glob) + + $ hg obslog + @ 6a022cbb61d5 (2) adda + | + x 07f494440405 (0) adda + rewritten(branch) as 6a022cbb61d5 by test (*) (glob) + $ hg branch foo $ hg branches @@ -147,6 +155,7 @@ --close-branch mark a branch as closed, hiding it from the branch list -s --secret use the secret phase for committing + -n --note VALUE store a note on amend -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns -m --message TEXT use text as commit message diff -r 875de4816c5b -r bd99cb54712b tests/test-corrupt.t --- a/tests/test-corrupt.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-corrupt.t Mon Dec 11 18:30:15 2017 +0100 @@ -101,6 +101,7 @@ $ hg prune --fold -n -1 -- -2 -3 + current hg version does not support storing note in obsmarker 2 changesets pruned $ hg push ../other pushing to ../other diff -r 875de4816c5b -r bd99cb54712b tests/test-discovery-obshashrange.t --- a/tests/test-discovery-obshashrange.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-discovery-obshashrange.t Mon Dec 11 18:30:15 2017 +0100 @@ -50,6 +50,8 @@ * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob) * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob) * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob) + * @0000000000000000000000000000000000000000 (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @0000000000000000000000000000000000000000 (*)> updated evo-ext-depthcache in *.???? seconds (8r) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (8r, 0o) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (8r, 0o) (glob) * @0000000000000000000000000000000000000000 (*)> debugbuilddag .+7 exited 0 after *.?? seconds (glob) @@ -92,6 +94,8 @@ * @0000000000000000000000000000000000000000 (*)> debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 66f7d451a68b85ed82ff5fcc254daf50c74144bd (glob) * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob) * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob) + * @0000000000000000000000000000000000000000 (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @0000000000000000000000000000000000000000 (*)> updated evo-ext-depthcache in *.???? seconds (8r) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) * @0000000000000000000000000000000000000000 (*)> debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 66f7d451a68b85ed82ff5fcc254daf50c74144bd exited 0 after *.?? seconds (glob) @@ -102,6 +106,8 @@ * @0000000000000000000000000000000000000000 (*)> debugobsolete cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d (glob) * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob) * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob) + * @0000000000000000000000000000000000000000 (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @0000000000000000000000000000000000000000 (*)> updated evo-ext-depthcache in *.???? seconds (8r) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 2o) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) * @0000000000000000000000000000000000000000 (*)> debugobsolete cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d exited 0 after *.?? seconds (glob) @@ -112,6 +118,8 @@ * @0000000000000000000000000000000000000000 (*)> debugobsolete eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 4de32a90b66cd083ebf3c00b41277aa7abca51dd (glob) * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob) * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob) + * @0000000000000000000000000000000000000000 (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @0000000000000000000000000000000000000000 (*)> updated evo-ext-depthcache in *.???? seconds (8r) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 2o) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) * @0000000000000000000000000000000000000000 (*)> debugobsolete eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 4de32a90b66cd083ebf3c00b41277aa7abca51dd exited 0 after *.?? seconds (glob) @@ -153,6 +161,8 @@ (run 'hg update' to get a working copy) $ hg -R ../server blackbox * @0000000000000000000000000000000000000000 (*)> debugobshashrange --subranges --rev tip (glob) + * @0000000000000000000000000000000000000000 (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @0000000000000000000000000000000000000000 (*)> updated evo-ext-depthcache in *.???? seconds (8r) (glob) * @0000000000000000000000000000000000000000 (*)> updated stablerange cache in *.???? seconds (glob) * @0000000000000000000000000000000000000000 (*)> debugobshashrange --subranges --rev tip exited 0 after *.?? seconds (glob) * @0000000000000000000000000000000000000000 (*)> serve --stdio (glob) @@ -168,6 +178,8 @@ * @0000000000000000000000000000000000000000 (*)> pull --rev 4 (glob) * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob) * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 1 nodes (glob) + * @0000000000000000000000000000000000000000 (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @0000000000000000000000000000000000000000 (*)> updated evo-ext-depthcache in *.???? seconds (5r) (glob) * @0000000000000000000000000000000000000000 (*)> updated stablerange cache in *.???? seconds (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (5r, 3o) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (5r, 3o) (glob) @@ -251,6 +263,7 @@ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob) * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob) * @0000000000000000000000000000000000000000 (*)> wrote served branch cache with 1 labels and 2 nodes (glob) + * @0000000000000000000000000000000000000000 (*)> updated evo-ext-depthcache in *.???? seconds (1r) (glob) * @0000000000000000000000000000000000000000 (*)> updated stablerange cache in *.???? seconds (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) @@ -313,15 +326,18 @@ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated served branch cache in *.???? seconds (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote served branch cache with 1 labels and 1 nodes (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-depthcache in *.???? seconds (1r) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 0o) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> commit -m foo exited 0 after *.?? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-depthcache in *.???? seconds (1r) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e exited 0 after *.?? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push -f --debug (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-depthcache in *.???? seconds (1r) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 0/5 mismatch - 1 obshashrange queries in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push -f --debug exited 0 after *.?? seconds (glob) @@ -424,6 +440,7 @@ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (2r, 0o) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 2 nodes (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-depthcache in *.???? seconds (2r) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (2r, 3o) (glob) @@ -570,6 +587,7 @@ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated served branch cache in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote served branch cache with 1 labels and 2 nodes (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-depthcache in *.???? seconds (1r) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) @@ -611,6 +629,8 @@ (run 'hg update' to get a working copy) $ hg blackbox * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-depthcache in *.???? seconds (8r) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip detected, evo-ext-obshashrange cache reset (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (8r, 12o) (glob) @@ -619,6 +639,7 @@ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 0/8 mismatch - 1 obshashrange queries in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip detected, evo-ext-obscache cache reset (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (9r, 12o) (glob) + * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-depthcache in *.???? seconds (1r) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 1o) (glob) * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) @@ -728,9 +749,12 @@ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> strip -r desc("foo") (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> saved backup bundle to $TESTTMP/client/.hg/strip-backup/45f8b879de92-94c82517-backup.hg (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> strip detected, evo-ext-obshashrange cache reset (glob) + * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> strip detected, evo-ext-depthcache cache reset (glob) + * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-depthcache in *.???? seconds (5r) (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (5r, 13o) (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> strip detected, evo-ext-obscache cache reset (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (5r, 13o) (glob) + * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-depthcache in *.???? seconds (3r) (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated stablerange cache in *.???? seconds (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (3r, 0o) (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (3r, 0o) (glob) @@ -744,6 +768,7 @@ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> pull (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> obsdiscovery, 0/8 mismatch - 1 obshashrange queries in *.???? seconds (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obscache in *.???? seconds (1r, 0o) (glob) + * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-depthcache in *.???? seconds (1r) (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated stablerange cache in *.???? seconds (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 0o) (glob) * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated served branch cache in *.???? seconds (glob) diff -r 875de4816c5b -r bd99cb54712b tests/test-evolve-obshistory-complex.t --- a/tests/test-evolve-obshistory-complex.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-evolve-obshistory-complex.t Mon Dec 11 18:30:15 2017 +0100 @@ -71,9 +71,21 @@ 4 new unstable changesets $ hg fold --exact -r 3 -r 4 --date "0 0" -m "fold1" 2 changesets folded - $ hg fold --exact -r 5 -r 6 --date "0 0" -m "fold2" + $ hg fold --exact -r 5 -r 6 --date "0 0" -m "fold2" -n "folding changesets to test" + current hg version does not support storing note in obsmarker 2 changesets folded 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg obslog -r . + @ 100cc25b765f (9) fold2 + |\ + x | 0da815c333f6 (5) E + / rewritten(description, content) as 100cc25b765f by test (*) (glob) + | note: folding changesets to test + | + x d9f908fde1a1 (6) F + rewritten(description, parent, content) as 100cc25b765f by test (*) (glob) + note: folding changesets to test + $ hg log -G @ changeset: 9:100cc25b765f | tag: tip @@ -297,7 +309,8 @@ $ hg prune -s 12 -r 11 1 changesets pruned - $ hg prune -s 14 -r 13 + $ hg prune -s 14 -r 13 -n "this is a note stored in obsmarker in prune" + current hg version does not support storing note in obsmarker 1 changesets pruned $ hg log -G @ changeset: 15:d4a000f63ee9 @@ -398,12 +411,14 @@ | | | | | | | +-------x d0f33db50670 (13) fold1 | | | | | rewritten(description, parent, content) as ec31316faa9d by test (*) (glob) + | | | | | note: this is a note stored in obsmarker in prune | | | | | +---x | | e036916b63ea (11) fold0 | | / / rewritten(description, parent, content) as 7b3290f6e0a0 by test (*) (glob) | | | | | | x | 0da815c333f6 (5) E | | / rewritten(description, content) as 100cc25b765f by test (*) (glob) + | | | note: folding changesets to test | | | x | | b868bc49b0a4 (7) fold0 |\ \ \ rewritten(parent, content) as 19e14c8397fc, e036916b63ea by test (*) (glob) @@ -413,6 +428,7 @@ | | | | | | | | | x d9f908fde1a1 (6) F | | | | rewritten(description, parent, content) as 100cc25b765f by test (*) (glob) + | | | | note: folding changesets to test | | | | x | | | 2a34000d3544 (1) A / / / rewritten(description, content) as b868bc49b0a4 by test (*) (glob) diff -r 875de4816c5b -r bd99cb54712b tests/test-evolve-obshistory.t --- a/tests/test-evolve-obshistory.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-evolve-obshistory.t Mon Dec 11 18:30:15 2017 +0100 @@ -312,7 +312,7 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: ROOT - $ hg split -r 'desc(A0)' -d "0 0" << EOF + $ hg split -r 'desc(A0)' -n "testing split" -d "0 0" << EOF > y > y > n @@ -320,6 +320,7 @@ > y > y > EOF + current hg version does not support storing note in obsmarker 0 files updated, 0 files merged, 2 files removed, 0 files unresolved adding a adding b @@ -377,6 +378,7 @@ $ hg obslog 471597cad322 --hidden --patch x 471597cad322 (1) A0 rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob) + note: testing split (No patch available, too many successors (2)) $ hg obslog 471597cad322 --hidden --no-graph -Tjson | python -m json.tool @@ -392,6 +394,7 @@ "parent", "content" ], + "note": "testing split", "succnodes": [ "337fec4d2edc", "f257fde29c7a" @@ -412,6 +415,7 @@ | x 471597cad322 (1) A0 rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob) + note: testing split (No patch available, too many successors (2)) With the all option, it should show the three changesets @@ -422,6 +426,7 @@ |/ x 471597cad322 (1) A0 rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob) + note: testing split (No patch available, too many successors (2)) Check that debugobshistory on the second successor after split show @@ -431,6 +436,7 @@ | x 471597cad322 (1) A0 rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob) + note: testing split (No patch available, too many successors (2)) With the all option, it should show the three changesets @@ -441,6 +447,7 @@ |/ x 471597cad322 (1) A0 rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob) + note: testing split (No patch available, too many successors (2)) Obslog with all option all should also works on the splitted commit @@ -451,6 +458,7 @@ |/ x 471597cad322 (1) A0 rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob) + note: testing split (No patch available, too many successors (2)) Check that debugobshistory on both successors after split show @@ -462,6 +470,7 @@ |/ x 471597cad322 (1) A0 rewritten(parent, content) as 337fec4d2edc, f257fde29c7a by test (*) (glob) + note: testing split (No patch available, too many successors (2)) $ hg update 471597cad322 diff -r 875de4816c5b -r bd99cb54712b tests/test-metaedit.t --- a/tests/test-metaedit.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-metaedit.t Mon Dec 11 18:30:15 2017 +0100 @@ -137,7 +137,13 @@ abort: editing multiple revisions without --fold is not currently supported [255] - $ HGEDITOR=cat hg metaedit '.^::.' --fold + $ HGEDITOR=cat hg metaedit '.^::.' --fold --note 'folding changesets using metaedit, + > and newlines' + current hg version does not support storing note in obsmarker + abort: note cannot contain a newline + [255] + $ HGEDITOR=cat hg metaedit '.^::.' --fold --note "folding changesets using metaedit" + current hg version does not support storing note in obsmarker HG: This is a fold of 2 changesets. HG: Commit message of changeset 7. @@ -164,6 +170,21 @@ | ~ + $ hg obslog -r . + @ a08d35fd7d9d (10) E + |\ + x | 212b2a2b87cd (9) F + | | rewritten(description, user, parent, content) as a08d35fd7d9d by test (*) (glob) + | | note: folding changesets using metaedit + | | + | x c2bd843aa246 (7) E + | rewritten(description, content) as a08d35fd7d9d by test (*) (glob) + | note: folding changesets using metaedit + | + x 587528abfffe (8) F + rewritten(user) as 212b2a2b87cd by test (*) (glob) + + no new commit is created here because the date is the same $ HGEDITOR=cat hg metaedit E diff -r 875de4816c5b -r bd99cb54712b tests/test-minitopic.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-minitopic.t Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,238 @@ + $ . $TESTDIR/testlib/common.sh + +setup + $ cat >> $HGRCPATH << EOF + > [extensions] + > share= + > blackbox= + > [web] + > allow_push = * + > push_ssl = no + > [phases] + > publish = False + > [paths] + > enabled = http://localhost:$HGPORT/ + > disabled = http://localhost:$HGPORT2/ + > EOF + + $ hg init ./server-enabled + $ cat >> server-enabled/.hg/hgrc << EOF + > [extensions] + > serverminitopic= + > [experimental] + > server-mini-topic = yes + > EOF + + $ hg share ./server-enabled ./server-disabled + updating working directory + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cat >> server-disabled/.hg/hgrc << EOF + > [extensions] + > serverminitopic= + > [experimental] + > server-mini-topic = no + > EOF + + $ hg init client-disabled + $ hg init client-enabled + $ cat >> client-enabled/.hg/hgrc << EOF + > [extensions] + > topic= + > EOF + + $ hg serve -R server-enabled -p $HGPORT -d --pid-file hg1.pid --errorlog hg1.error + $ cat hg1.pid > $DAEMON_PIDS + $ hg serve -R server-disabled -p $HGPORT2 -d --pid-file hg2.pid --errorlog hg2.error + $ cat hg2.pid >> $DAEMON_PIDS + + $ curl --silent http://localhost:$HGPORT/?cmd=capabilities | grep -o topics + topics + $ curl --silent http://localhost:$HGPORT2/?cmd=capabilities | grep -o topics + [1] + +Pushing first changesets to the servers +-------------------------------------- + + $ cd client-enabled + $ mkcommit c_A0 + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + $ mkcommit c_B0 + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error + +Pushing new head +---------------- + + $ hg up 'desc("c_A0")' + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ mkcommit c_C0 + created new head + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + abort: push creates new remote head 22c9514ed811! + (merge or see 'hg help push' for details about pushing new heads) + [255] + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + abort: push creates new remote head 22c9514ed811! + (merge or see 'hg help push' for details about pushing new heads) + [255] + + $ curl --silent http://localhost:$HGPORT/?cmd=branchmap | sort + default 0ab6d544d0efd629fda056601cfe95e73d1af210 + $ curl --silent http://localhost:$HGPORT2/?cmd=branchmap | sort + default 0ab6d544d0efd629fda056601cfe95e73d1af210 + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error + +Pushing new topic +----------------- + + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ mkcommit c_D0 + $ hg log -G + @ changeset: 3:9c660cf97499 + |\ tag: tip + | | parent: 2:22c9514ed811 + | | parent: 1:0ab6d544d0ef + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_D0 + | | + | o changeset: 2:22c9514ed811 + | | parent: 0:14faebcf9752 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_C0 + | | + o | changeset: 1:0ab6d544d0ef + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_B0 + | + o changeset: 0:14faebcf9752 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: c_A0 + + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 2 changesets with 2 changes to 2 files + $ hg up 'desc("c_C0")' + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ hg topic topic_A + marked working directory as topic: topic_A + $ mkcommit c_E0 + active topic 'topic_A' grew its first changeset + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + abort: push creates new remote head f31af349535e! + (merge or see 'hg help push' for details about pushing new heads) + [255] + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files (+1 heads) + + $ curl --silent http://localhost:$HGPORT/?cmd=branchmap | sort + default 9c660cf97499ae01ccb6894880455c6ffa4b19cf + default%3Atopic_A f31af349535e413b6023f11b51a6afccf4139180 + $ curl --silent http://localhost:$HGPORT2/?cmd=branchmap | sort + default 9c660cf97499ae01ccb6894880455c6ffa4b19cf f31af349535e413b6023f11b51a6afccf4139180 + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error + +Pushing new head to a topic +--------------------------- + + $ hg up 'desc("c_D0")' + 2 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg topic topic_A + marked working directory as topic: topic_A + $ mkcommit c_F0 + $ hg log -G + @ changeset: 5:82c5842e0472 + | tag: tip + | topic: topic_A + | parent: 3:9c660cf97499 + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_F0 + | + | o changeset: 4:f31af349535e + | | topic: topic_A + | | parent: 2:22c9514ed811 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_E0 + | | + o | changeset: 3:9c660cf97499 + |\| parent: 2:22c9514ed811 + | | parent: 1:0ab6d544d0ef + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_D0 + | | + | o changeset: 2:22c9514ed811 + | | parent: 0:14faebcf9752 + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | summary: c_C0 + | | + o | changeset: 1:0ab6d544d0ef + |/ user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: c_B0 + | + o changeset: 0:14faebcf9752 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: c_A0 + + $ hg push enabled + pushing to http://localhost:$HGPORT/ + searching for changes + abort: push creates new remote head 82c5842e0472 on branch 'default:topic_A'! + (merge or see 'hg help push' for details about pushing new heads) + [255] + $ hg push disabled + pushing to http://localhost:$HGPORT2/ + searching for changes + remote: adding changesets + remote: adding manifests + remote: adding file changes + remote: added 1 changesets with 1 changes to 1 files + + $ curl --silent http://localhost:$HGPORT/?cmd=branchmap | sort + default 9c660cf97499ae01ccb6894880455c6ffa4b19cf + default%3Atopic_A f31af349535e413b6023f11b51a6afccf4139180 82c5842e047215160763f81ae93ae42c65b20a63 + $ curl --silent http://localhost:$HGPORT2/?cmd=branchmap | sort + default f31af349535e413b6023f11b51a6afccf4139180 82c5842e047215160763f81ae93ae42c65b20a63 + $ cat $TESTTMP/hg1.error + $ cat $TESTTMP/hg2.error diff -r 875de4816c5b -r bd99cb54712b tests/test-prev-next.t --- a/tests/test-prev-next.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-prev-next.t Mon Dec 11 18:30:15 2017 +0100 @@ -4,7 +4,7 @@ > EOF $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH -hg prev -B should move active bookmark +hg prev & next move to parent/child $ hg init test-repo $ cd test-repo $ touch a @@ -13,6 +13,18 @@ $ touch b $ hg add b $ hg commit -m 'added b' + $ hg prev + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + [0] added a + $ hg next + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + [1] added b + +hg prev & next respect --quiet + $ hg prev -q + $ hg next -q + +hg prev -B should move active bookmark $ hg bookmark mark $ hg bookmarks * mark 1:6e742c9127b3 diff -r 875de4816c5b -r bd99cb54712b tests/test-stablerange-branchpoint.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-stablerange-branchpoint.t Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,731 @@ +Test for stable ordering capabilities +===================================== + + $ . $TESTDIR/testlib/pythonpath.sh + + $ cat << EOF >> $HGRCPATH + > [extensions] + > hgext3rd.evolve = + > [ui] + > logtemplate = "{rev} {node|short} {desc} {tags}\n" + > [defaults] + > debugstablerange = --method branchpoint + > EOF + +Simple linear test +================== + + $ hg init repo_linear + $ cd repo_linear + $ hg debugbuilddag '.+6' + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + c8d03c1b5e94 6 + f69452c5b1af 7 + $ hg debugstablerange --verify --verbose --subranges --rev 1 + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 1 > 1.range + +bigger subset reuse most of the previous one + + $ hg debugstablerange --verify --verbose --subranges --rev 4 + bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 4 > 4.range + $ diff -u 1.range 4.range + --- 1.range * (glob) + +++ 4.range * (glob) + @@ -1,3 +1,9 @@ + +bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + +2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + +01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + +2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + +bebd167eb94d-4 (4, 5, 1) [leaf] - + [1] + +Using a range not ending on 2**N boundary +we fall back on 2**N as much as possible + + $ hg debugstablerange --verify --verbose --subranges --rev 5 + c8d03c1b5e94-0 (5, 6, 6) [complete] - 2dc09a01254d-0 (3, 4, 4), c8d03c1b5e94-4 (5, 6, 2) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + c8d03c1b5e94-4 (5, 6, 2) [complete] - bebd167eb94d-4 (4, 5, 1), c8d03c1b5e94-5 (5, 6, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + c8d03c1b5e94-5 (5, 6, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 5 > 5.range + $ diff -u 4.range 5.range + --- 4.range * (glob) + +++ 5.range * (glob) + @@ -1,9 +1,11 @@ + -bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + +c8d03c1b5e94-0 (5, 6, 6) [complete] - 2dc09a01254d-0 (3, 4, 4), c8d03c1b5e94-4 (5, 6, 2) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + +c8d03c1b5e94-4 (5, 6, 2) [complete] - bebd167eb94d-4 (4, 5, 1), c8d03c1b5e94-5 (5, 6, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + +c8d03c1b5e94-5 (5, 6, 1) [leaf] - + [1] + +Even two unperfect range overlap a lot + + $ hg debugstablerange --verify --verbose --subranges --rev tip + f69452c5b1af-0 (6, 7, 7) [complete] - 2dc09a01254d-0 (3, 4, 4), f69452c5b1af-4 (6, 7, 3) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + f69452c5b1af-4 (6, 7, 3) [complete] - c8d03c1b5e94-4 (5, 6, 2), f69452c5b1af-6 (6, 7, 1) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + c8d03c1b5e94-4 (5, 6, 2) [complete] - bebd167eb94d-4 (4, 5, 1), c8d03c1b5e94-5 (5, 6, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + c8d03c1b5e94-5 (5, 6, 1) [leaf] - + f69452c5b1af-6 (6, 7, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev tip > tip.range + $ diff -u 5.range tip.range + --- 5.range * (glob) + +++ tip.range * (glob) + @@ -1,5 +1,6 @@ + -c8d03c1b5e94-0 (5, 6, 6) [complete] - 2dc09a01254d-0 (3, 4, 4), c8d03c1b5e94-4 (5, 6, 2) + +f69452c5b1af-0 (6, 7, 7) [complete] - 2dc09a01254d-0 (3, 4, 4), f69452c5b1af-4 (6, 7, 3) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +f69452c5b1af-4 (6, 7, 3) [complete] - c8d03c1b5e94-4 (5, 6, 2), f69452c5b1af-6 (6, 7, 1) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + c8d03c1b5e94-4 (5, 6, 2) [complete] - bebd167eb94d-4 (4, 5, 1), c8d03c1b5e94-5 (5, 6, 1) + @@ -9,3 +10,4 @@ + 66f7d451a68b-1 (1, 2, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + c8d03c1b5e94-5 (5, 6, 1) [leaf] - + +f69452c5b1af-6 (6, 7, 1) [leaf] - + [1] + + $ cd .. + +Case with merge +=============== + +Simple case: branching is on a boundary +-------------------------------------------- + + $ hg init repo_merge_split_on_boundary + $ cd repo_merge_split_on_boundary + $ hg debugbuilddag '.:base + > +3:left + > +2:head + > ' + $ hg log -G + o 9 0338daf18215 r9 head tip + | + o 8 71b32fcf3f71 r8 + | + o 7 5f18015f9110 r7 merge + |\ + | o 6 a2f58e9c1e56 r6 right + | | + | o 5 3a367db1fabc r5 + | | + | o 4 e7bd5218ca15 r4 + | | + o | 3 2dc09a01254d r3 left + | | + o | 2 01241442b3c2 r2 + | | + o | 1 66f7d451a68b r1 + |/ + o 0 1ea73414a91b r0 base + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + e7bd5218ca15 2 + 3a367db1fabc 3 + a2f58e9c1e56 4 + 5f18015f9110 8 + 71b32fcf3f71 9 + 0338daf18215 10 + +Each of the linear branch reuse range internally + +(left branch) + + $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' > left-2.range + $ hg debugstablerange --verify --verbose --subranges --rev left + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'left' > left.range + $ diff -u left-2.range left.range + --- left-2.range * (glob) + +++ left.range * (glob) + @@ -1,3 +1,7 @@ + +2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + +01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + +2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + [1] + +(right branch) + + $ hg debugstablerange --verify --verbose --subranges --rev right~2 + e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + e7bd5218ca15-1 (4, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'right~2' > right-2.range + $ hg debugstablerange --verify --verbose --subranges --rev right + a2f58e9c1e56-0 (6, 4, 4) [complete] - e7bd5218ca15-0 (4, 2, 2), a2f58e9c1e56-2 (6, 4, 2) + a2f58e9c1e56-2 (6, 4, 2) [complete] - 3a367db1fabc-2 (5, 3, 1), a2f58e9c1e56-3 (6, 4, 1) + e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 3a367db1fabc-2 (5, 3, 1) [leaf] - + a2f58e9c1e56-3 (6, 4, 1) [leaf] - + e7bd5218ca15-1 (4, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'right' > right.range + $ diff -u right-2.range right.range + --- right-2.range * (glob) + +++ right.range * (glob) + @@ -1,3 +1,7 @@ + +a2f58e9c1e56-0 (6, 4, 4) [complete] - e7bd5218ca15-0 (4, 2, 2), a2f58e9c1e56-2 (6, 4, 2) + +a2f58e9c1e56-2 (6, 4, 2) [complete] - 3a367db1fabc-2 (5, 3, 1), a2f58e9c1e56-3 (6, 4, 1) + e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + +3a367db1fabc-2 (5, 3, 1) [leaf] - + +a2f58e9c1e56-3 (6, 4, 1) [leaf] - + e7bd5218ca15-1 (4, 2, 1) [leaf] - + [1] + +The merge reuse as much of the slicing created for one of the branch + + $ hg debugstablerange --verify --verbose --subranges --rev merge + 5f18015f9110-0 (7, 8, 8) [complete] - 2dc09a01254d-0 (3, 4, 4), 5f18015f9110-4 (7, 8, 4) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 5f18015f9110-4 (7, 8, 4) [complete] - 3a367db1fabc-1 (5, 3, 2), 5f18015f9110-6 (7, 8, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 3a367db1fabc-1 (5, 3, 2) [complete] - e7bd5218ca15-1 (4, 2, 1), 3a367db1fabc-2 (5, 3, 1) + 5f18015f9110-6 (7, 8, 2) [complete] - a2f58e9c1e56-3 (6, 4, 1), 5f18015f9110-7 (7, 8, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 3a367db1fabc-2 (5, 3, 1) [leaf] - + 5f18015f9110-7 (7, 8, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + a2f58e9c1e56-3 (6, 4, 1) [leaf] - + e7bd5218ca15-1 (4, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'merge' > merge.range + $ diff -u left.range merge.range + --- left.range * (glob) + +++ merge.range * (glob) + @@ -1,7 +1,15 @@ + +5f18015f9110-0 (7, 8, 8) [complete] - 2dc09a01254d-0 (3, 4, 4), 5f18015f9110-4 (7, 8, 4) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +5f18015f9110-4 (7, 8, 4) [complete] - 3a367db1fabc-1 (5, 3, 2), 5f18015f9110-6 (7, 8, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + +3a367db1fabc-1 (5, 3, 2) [complete] - e7bd5218ca15-1 (4, 2, 1), 3a367db1fabc-2 (5, 3, 1) + +5f18015f9110-6 (7, 8, 2) [complete] - a2f58e9c1e56-3 (6, 4, 1), 5f18015f9110-7 (7, 8, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + +3a367db1fabc-2 (5, 3, 1) [leaf] - + +5f18015f9110-7 (7, 8, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + +a2f58e9c1e56-3 (6, 4, 1) [leaf] - + +e7bd5218ca15-1 (4, 2, 1) [leaf] - + [1] + $ diff -u right.range merge.range + --- right.range * (glob) + +++ merge.range * (glob) + @@ -1,7 +1,15 @@ + -a2f58e9c1e56-0 (6, 4, 4) [complete] - e7bd5218ca15-0 (4, 2, 2), a2f58e9c1e56-2 (6, 4, 2) + -a2f58e9c1e56-2 (6, 4, 2) [complete] - 3a367db1fabc-2 (5, 3, 1), a2f58e9c1e56-3 (6, 4, 1) + -e7bd5218ca15-0 (4, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), e7bd5218ca15-1 (4, 2, 1) + +5f18015f9110-0 (7, 8, 8) [complete] - 2dc09a01254d-0 (3, 4, 4), 5f18015f9110-4 (7, 8, 4) + +2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +5f18015f9110-4 (7, 8, 4) [complete] - 3a367db1fabc-1 (5, 3, 2), 5f18015f9110-6 (7, 8, 2) + +2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + +3a367db1fabc-1 (5, 3, 2) [complete] - e7bd5218ca15-1 (4, 2, 1), 3a367db1fabc-2 (5, 3, 1) + +5f18015f9110-6 (7, 8, 2) [complete] - a2f58e9c1e56-3 (6, 4, 1), 5f18015f9110-7 (7, 8, 1) + +66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + +01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + +2dc09a01254d-3 (3, 4, 1) [leaf] - + 3a367db1fabc-2 (5, 3, 1) [leaf] - + +5f18015f9110-7 (7, 8, 1) [leaf] - + +66f7d451a68b-1 (1, 2, 1) [leaf] - + a2f58e9c1e56-3 (6, 4, 1) [leaf] - + e7bd5218ca15-1 (4, 2, 1) [leaf] - + [1] + $ cd .. + +slice create multiple heads +--------------------------- + + $ hg init repo_merge_split_heads + $ cd repo_merge_split_heads + $ hg debugbuilddag '.:base + > +4:left + > +2:head + > ' + $ hg debugbuilddag '.:base + > +3:left + > +2:head + > ' + abort: repository is not empty + [255] + $ hg log -G + o 12 e6b8d5b46647 r12 head tip + | + o 11 485383494a89 r11 + | + o 10 8aca7f8c9bd2 r10 merge + |\ + | o 9 f4b7da68b467 r9 right + | | + | o 8 857477a9aebb r8 + | | + | o 7 42b07e8da27d r7 + | | + | o 6 b9bc20507e0b r6 + | | + | o 5 de561312eff4 r5 + | | + o | 4 bebd167eb94d r4 left + | | + o | 3 2dc09a01254d r3 + | | + o | 2 01241442b3c2 r2 + | | + o | 1 66f7d451a68b r1 + |/ + o 0 1ea73414a91b r0 base + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + de561312eff4 2 + b9bc20507e0b 3 + 42b07e8da27d 4 + 857477a9aebb 5 + f4b7da68b467 6 + 8aca7f8c9bd2 11 + 485383494a89 12 + e6b8d5b46647 13 + +Each of the linear branch reuse range internally + +(left branch) + + $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' + 01241442b3c2-0 (2, 3, 3) [complete] - 66f7d451a68b-0 (1, 2, 2), 01241442b3c2-2 (2, 3, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'left~2' > left-2.range + $ hg debugstablerange --verify --verbose --subranges --rev left + bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'left' > left.range + $ diff -u left-2.range left.range + --- left-2.range * (glob) + +++ left.range * (glob) + @@ -1,5 +1,9 @@ + -01241442b3c2-0 (2, 3, 3) [complete] - 66f7d451a68b-0 (1, 2, 2), 01241442b3c2-2 (2, 3, 1) + +bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + +2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + +2dc09a01254d-3 (3, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + +bebd167eb94d-4 (4, 5, 1) [leaf] - + [1] + +(right branch) + + $ hg debugstablerange --verify --verbose --subranges --rev right~2 + 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 42b07e8da27d-3 (7, 4, 1) [leaf] - + b9bc20507e0b-2 (6, 3, 1) [leaf] - + de561312eff4-1 (5, 2, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'right~2' > right-2.range + $ hg debugstablerange --verify --verbose --subranges --rev right + f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) + 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) + f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 42b07e8da27d-3 (7, 4, 1) [leaf] - + 857477a9aebb-4 (8, 5, 1) [leaf] - + b9bc20507e0b-2 (6, 3, 1) [leaf] - + de561312eff4-1 (5, 2, 1) [leaf] - + f4b7da68b467-5 (9, 6, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'right' > right.range + $ diff -u right-2.range right.range + --- right-2.range * (glob) + +++ right.range * (glob) + @@ -1,7 +1,11 @@ + +f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) + 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) + +f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 42b07e8da27d-3 (7, 4, 1) [leaf] - + +857477a9aebb-4 (8, 5, 1) [leaf] - + b9bc20507e0b-2 (6, 3, 1) [leaf] - + de561312eff4-1 (5, 2, 1) [leaf] - + +f4b7da68b467-5 (9, 6, 1) [leaf] - + [1] + +In this case, the bottom of the split will have multiple heads, + +So we'll create more than 1 subrange out of it. + +We are still able to reuse one of the branch however + + $ hg debugstablerange --verify --verbose --subranges --rev merge + 8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) + bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) + 8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 42b07e8da27d-3 (7, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + 857477a9aebb-4 (8, 5, 1) [leaf] - + 8aca7f8c9bd2-10 (10, 11, 1) [leaf] - + b9bc20507e0b-2 (6, 3, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + de561312eff4-1 (5, 2, 1) [leaf] - + f4b7da68b467-5 (9, 6, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'merge' > merge.range + $ diff -u left.range merge.range + --- left.range * (glob) + +++ merge.range * (glob) + @@ -1,9 +1,20 @@ + +8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) + bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) + +8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + +42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + +f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + +42b07e8da27d-3 (7, 4, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + +857477a9aebb-4 (8, 5, 1) [leaf] - + +8aca7f8c9bd2-10 (10, 11, 1) [leaf] - + +b9bc20507e0b-2 (6, 3, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + +de561312eff4-1 (5, 2, 1) [leaf] - + +f4b7da68b467-5 (9, 6, 1) [leaf] - + [1] + $ diff -u right.range merge.range + --- right.range * (glob) + +++ merge.range * (glob) + @@ -1,11 +1,20 @@ + -f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) + -42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + +8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) + +bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + +2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) + +8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) + +2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + -de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) + +66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) + +01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + +2dc09a01254d-3 (3, 4, 1) [leaf] - + 42b07e8da27d-3 (7, 4, 1) [leaf] - + +66f7d451a68b-1 (1, 2, 1) [leaf] - + 857477a9aebb-4 (8, 5, 1) [leaf] - + +8aca7f8c9bd2-10 (10, 11, 1) [leaf] - + b9bc20507e0b-2 (6, 3, 1) [leaf] - + +bebd167eb94d-4 (4, 5, 1) [leaf] - + de561312eff4-1 (5, 2, 1) [leaf] - + f4b7da68b467-5 (9, 6, 1) [leaf] - + [1] + +Range above the merge, reuse subrange from the merge + + $ hg debugstablerange --verify --verbose --subranges --rev tip + e6b8d5b46647-0 (12, 13, 13) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), e6b8d5b46647-8 (12, 13, 5) + bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + e6b8d5b46647-8 (12, 13, 5) [complete] - 485383494a89-8 (11, 12, 4), e6b8d5b46647-12 (12, 13, 1) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + 485383494a89-8 (11, 12, 4) [complete] - f4b7da68b467-4 (9, 6, 2), 485383494a89-10 (11, 12, 2) + 42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + 485383494a89-10 (11, 12, 2) [complete] - 8aca7f8c9bd2-10 (10, 11, 1), 485383494a89-11 (11, 12, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 42b07e8da27d-3 (7, 4, 1) [leaf] - + 485383494a89-11 (11, 12, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + 857477a9aebb-4 (8, 5, 1) [leaf] - + 8aca7f8c9bd2-10 (10, 11, 1) [leaf] - + b9bc20507e0b-2 (6, 3, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + de561312eff4-1 (5, 2, 1) [leaf] - + e6b8d5b46647-12 (12, 13, 1) [leaf] - + f4b7da68b467-5 (9, 6, 1) [leaf] - + $ hg debugstablerange --verify --verbose --subranges --rev 'tip' > tip.range + $ diff -u merge.range tip.range + --- merge.range * (glob) + +++ tip.range * (glob) + @@ -1,20 +1,24 @@ + -8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) + +e6b8d5b46647-0 (12, 13, 13) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), e6b8d5b46647-8 (12, 13, 5) + bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) + +e6b8d5b46647-8 (12, 13, 5) [complete] - 485383494a89-8 (11, 12, 4), e6b8d5b46647-12 (12, 13, 1) + 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) + +485383494a89-8 (11, 12, 4) [complete] - f4b7da68b467-4 (9, 6, 2), 485383494a89-10 (11, 12, 2) + 42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) + -8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) + 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) + 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + +485383494a89-10 (11, 12, 2) [complete] - 8aca7f8c9bd2-10 (10, 11, 1), 485383494a89-11 (11, 12, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) + 01241442b3c2-2 (2, 3, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2dc09a01254d-3 (3, 4, 1) [leaf] - + 42b07e8da27d-3 (7, 4, 1) [leaf] - + +485383494a89-11 (11, 12, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + 857477a9aebb-4 (8, 5, 1) [leaf] - + 8aca7f8c9bd2-10 (10, 11, 1) [leaf] - + b9bc20507e0b-2 (6, 3, 1) [leaf] - + bebd167eb94d-4 (4, 5, 1) [leaf] - + de561312eff4-1 (5, 2, 1) [leaf] - + +e6b8d5b46647-12 (12, 13, 1) [leaf] - + f4b7da68b467-5 (9, 6, 1) [leaf] - + [1] + + $ cd .. + +Tests range with criss cross merge in the graph +=============================================== + + $ hg init repo_criss_cross + $ cd repo_criss_cross + $ hg debugbuilddag ' + > ..:g # 2 nodes, tagged "g" + > <2.:h # another node base one -2 -> 0, tagged "h" + > *1/2:m # merge -1 and -2 (1, 2), tagged "m" + > <2+2:i # 2 nodes based on -2, tag head as "i" + > .:c # 1 node tagged "c" + > <2.:b # 1 node based on -2; tagged "b" + > <2.:e # 1 node based on -2, tagged "e" + > ' + $ hg log -G + o 15 1d8d22637c2d r15 tip + |\ + | o 14 43227190fef8 r14 f + | | + | | o 13 b4594d867745 r13 e + | | | + | | | o 12 e46a4836065c r12 d + | | |/ + | | o 11 bab5d5bf48bd r11 + | |/ + | | o 10 ff43616e5d0f r10 b + | | | + | | | o 9 dcbb326fdec2 r9 a + | | |/ + | | o 8 d62d843c9a01 r8 + | | | + | | o 7 e7d9710d9fc6 r7 + | |/ + +---o 6 2702dd0c91e7 r6 c + | | + o | 5 f0f3ef9a6cd5 r5 i + | | + o | 4 4c748ffd1a46 r4 + | | + | o 3 2b6d669947cd r3 m + |/| + o | 2 fa942426a6fd r2 h + | | + | o 1 66f7d451a68b r1 g + |/ + o 0 1ea73414a91b r0 + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + fa942426a6fd 2 + 2b6d669947cd 4 + 4c748ffd1a46 3 + f0f3ef9a6cd5 4 + 2702dd0c91e7 5 + e7d9710d9fc6 5 + d62d843c9a01 6 + dcbb326fdec2 7 + ff43616e5d0f 7 + bab5d5bf48bd 5 + e46a4836065c 6 + b4594d867745 6 + 43227190fef8 5 + 1d8d22637c2d 8 + $ hg debugstablerange --verify --verbose --subranges --rev 'head()' + 1d8d22637c2d-0 (15, 8, 8) [complete] - 2b6d669947cd-0 (3, 4, 4), 1d8d22637c2d-4 (15, 8, 4) + dcbb326fdec2-0 (9, 7, 7) [complete] - 2b6d669947cd-0 (3, 4, 4), dcbb326fdec2-4 (9, 7, 3) + ff43616e5d0f-0 (10, 7, 7) [complete] - 2b6d669947cd-0 (3, 4, 4), ff43616e5d0f-4 (10, 7, 3) + b4594d867745-0 (13, 6, 6) [complete] - 2b6d669947cd-0 (3, 4, 4), b4594d867745-4 (13, 6, 2) + e46a4836065c-0 (12, 6, 6) [complete] - 2b6d669947cd-0 (3, 4, 4), e46a4836065c-4 (12, 6, 2) + 2702dd0c91e7-0 (6, 5, 5) [complete] - f0f3ef9a6cd5-0 (5, 4, 4), 2702dd0c91e7-4 (6, 5, 1) + 1d8d22637c2d-4 (15, 8, 4) [complete] - 43227190fef8-4 (14, 5, 1), 4c748ffd1a46-2 (4, 3, 1), 1d8d22637c2d-6 (15, 8, 2) + 2b6d669947cd-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2b6d669947cd-2 (3, 4, 2) + f0f3ef9a6cd5-0 (5, 4, 4) [complete] - fa942426a6fd-0 (2, 2, 2), f0f3ef9a6cd5-2 (5, 4, 2) + dcbb326fdec2-4 (9, 7, 3) [complete] - d62d843c9a01-4 (8, 6, 2), dcbb326fdec2-6 (9, 7, 1) + ff43616e5d0f-4 (10, 7, 3) [complete] - d62d843c9a01-4 (8, 6, 2), ff43616e5d0f-6 (10, 7, 1) + 1d8d22637c2d-6 (15, 8, 2) [complete] - f0f3ef9a6cd5-3 (5, 4, 1), 1d8d22637c2d-7 (15, 8, 1) + 2b6d669947cd-2 (3, 4, 2) [complete] - fa942426a6fd-1 (2, 2, 1), 2b6d669947cd-3 (3, 4, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + b4594d867745-4 (13, 6, 2) [complete] - bab5d5bf48bd-4 (11, 5, 1), b4594d867745-5 (13, 6, 1) + d62d843c9a01-4 (8, 6, 2) [complete] - e7d9710d9fc6-4 (7, 5, 1), d62d843c9a01-5 (8, 6, 1) + e46a4836065c-4 (12, 6, 2) [complete] - bab5d5bf48bd-4 (11, 5, 1), e46a4836065c-5 (12, 6, 1) + f0f3ef9a6cd5-2 (5, 4, 2) [complete] - 4c748ffd1a46-2 (4, 3, 1), f0f3ef9a6cd5-3 (5, 4, 1) + fa942426a6fd-0 (2, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), fa942426a6fd-1 (2, 2, 1) + 1d8d22637c2d-7 (15, 8, 1) [leaf] - + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 2702dd0c91e7-4 (6, 5, 1) [leaf] - + 2b6d669947cd-3 (3, 4, 1) [leaf] - + 43227190fef8-4 (14, 5, 1) [leaf] - + 4c748ffd1a46-2 (4, 3, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + b4594d867745-5 (13, 6, 1) [leaf] - + bab5d5bf48bd-4 (11, 5, 1) [leaf] - + d62d843c9a01-5 (8, 6, 1) [leaf] - + dcbb326fdec2-6 (9, 7, 1) [leaf] - + e46a4836065c-5 (12, 6, 1) [leaf] - + e7d9710d9fc6-4 (7, 5, 1) [leaf] - + f0f3ef9a6cd5-3 (5, 4, 1) [leaf] - + fa942426a6fd-1 (2, 2, 1) [leaf] - + ff43616e5d0f-6 (10, 7, 1) [leaf] - + $ cd .. + +Tests range where a toprange is rooted on a merge +================================================= + + $ hg init slice_on_merge + $ cd slice_on_merge + $ hg debugbuilddag ' + > ..:a # 2 nodes, tagged "a" + > <2..:b # another branch with two node based on 0, tagged b + > *a/b:m # merge -1 and -2 (1, 2), tagged "m" + > ' + $ hg log -G + o 4 f37e476fba9a r4 m tip + |\ + | o 3 36315563e2fa r3 b + | | + | o 2 fa942426a6fd r2 + | | + o | 1 66f7d451a68b r1 a + |/ + o 0 1ea73414a91b r0 + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + fa942426a6fd 2 + 36315563e2fa 3 + f37e476fba9a 5 + $ hg debugstablerange --verify --verbose --subranges --rev 'head()' + f37e476fba9a-0 (4, 5, 5) [complete] - 66f7d451a68b-0 (1, 2, 2), 36315563e2fa-1 (3, 3, 2), f37e476fba9a-4 (4, 5, 1) + 36315563e2fa-1 (3, 3, 2) [complete] - fa942426a6fd-1 (2, 2, 1), 36315563e2fa-2 (3, 3, 1) + 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) + 1ea73414a91b-0 (0, 1, 1) [leaf] - + 36315563e2fa-2 (3, 3, 1) [leaf] - + 66f7d451a68b-1 (1, 2, 1) [leaf] - + f37e476fba9a-4 (4, 5, 1) [leaf] - + fa942426a6fd-1 (2, 2, 1) [leaf] - + diff -r 875de4816c5b -r bd99cb54712b tests/test-stablerange.t --- a/tests/test-stablerange.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-stablerange.t Mon Dec 11 18:30:15 2017 +0100 @@ -8,6 +8,8 @@ > hgext3rd.evolve = > [ui] > logtemplate = "{rev} {node|short} {desc} {tags}\n" + > [defaults] + > debugstablerange = --method mergepoint > EOF Simple linear test @@ -16,6 +18,14 @@ $ hg init repo_linear $ cd repo_linear $ hg debugbuilddag '.+6' + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + c8d03c1b5e94 6 + f69452c5b1af 7 $ hg debugstablerange --verify --verbose --subranges --rev 1 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - @@ -156,6 +166,17 @@ |/ o 0 1ea73414a91b r0 base + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + e7bd5218ca15 2 + 3a367db1fabc 3 + a2f58e9c1e56 4 + 5f18015f9110 8 + 71b32fcf3f71 9 + 0338daf18215 10 Each of the linear branch reuse range internally @@ -327,6 +348,20 @@ |/ o 0 1ea73414a91b r0 base + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + de561312eff4 2 + b9bc20507e0b 3 + 42b07e8da27d 4 + 857477a9aebb 5 + f4b7da68b467 6 + 8aca7f8c9bd2 11 + 485383494a89 12 + e6b8d5b46647 13 Each of the linear branch reuse range internally @@ -414,15 +449,14 @@ We are still able to reuse one of the branch however $ hg debugstablerange --verify --verbose --subranges --rev merge - 8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-0 (7, 4, 4), 8aca7f8c9bd2-8 (10, 11, 3) + 8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) - 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + 42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) 8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) - de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) 01241442b3c2-2 (2, 3, 1) [leaf] - 1ea73414a91b-0 (0, 1, 1) [leaf] - @@ -439,16 +473,15 @@ $ diff -u left.range merge.range --- left.range * (glob) +++ merge.range * (glob) - @@ -1,9 +1,21 @@ - +8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-0 (7, 4, 4), 8aca7f8c9bd2-8 (10, 11, 3) + @@ -1,9 +1,20 @@ + +8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) - +42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + +42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) +8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) +42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) - +de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) +f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) 01241442b3c2-2 (2, 3, 1) [leaf] - 1ea73414a91b-0 (0, 1, 1) [leaf] - @@ -465,17 +498,18 @@ $ diff -u right.range merge.range --- right.range * (glob) +++ merge.range * (glob) - @@ -1,11 +1,21 @@ + @@ -1,11 +1,20 @@ -f4b7da68b467-0 (9, 6, 6) [complete] - 42b07e8da27d-0 (7, 4, 4), f4b7da68b467-4 (9, 6, 2) - +8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-0 (7, 4, 4), 8aca7f8c9bd2-8 (10, 11, 3) + -42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + +8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) +bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) +2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) - 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + +42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) +8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) +2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) + -de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) +66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) - de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) +01241442b3c2-2 (2, 3, 1) [leaf] - 1ea73414a91b-0 (0, 1, 1) [leaf] - @@ -493,17 +527,16 @@ Range above the merge, reuse subrange from the merge $ hg debugstablerange --verify --verbose --subranges --rev tip - e6b8d5b46647-0 (12, 13, 13) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-0 (7, 4, 4), e6b8d5b46647-8 (12, 13, 5) + e6b8d5b46647-0 (12, 13, 13) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), e6b8d5b46647-8 (12, 13, 5) bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) e6b8d5b46647-8 (12, 13, 5) [complete] - 485383494a89-8 (11, 12, 4), e6b8d5b46647-12 (12, 13, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) - 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) 485383494a89-8 (11, 12, 4) [complete] - f4b7da68b467-4 (9, 6, 2), 485383494a89-10 (11, 12, 2) + 42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) 485383494a89-10 (11, 12, 2) [complete] - 8aca7f8c9bd2-10 (10, 11, 1), 485383494a89-11 (11, 12, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) - de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) 01241442b3c2-2 (2, 3, 1) [leaf] - 1ea73414a91b-0 (0, 1, 1) [leaf] - @@ -522,22 +555,21 @@ $ diff -u merge.range tip.range --- merge.range * (glob) +++ tip.range * (glob) - @@ -1,10 +1,12 @@ - -8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-0 (7, 4, 4), 8aca7f8c9bd2-8 (10, 11, 3) - +e6b8d5b46647-0 (12, 13, 13) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-0 (7, 4, 4), e6b8d5b46647-8 (12, 13, 5) + @@ -1,20 +1,24 @@ + -8aca7f8c9bd2-0 (10, 11, 11) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), 8aca7f8c9bd2-8 (10, 11, 3) + +e6b8d5b46647-0 (12, 13, 13) [complete] - bebd167eb94d-0 (4, 5, 5), 42b07e8da27d-1 (7, 4, 3), e6b8d5b46647-8 (12, 13, 5) bebd167eb94d-0 (4, 5, 5) [complete] - 2dc09a01254d-0 (3, 4, 4), bebd167eb94d-4 (4, 5, 1) +e6b8d5b46647-8 (12, 13, 5) [complete] - 485383494a89-8 (11, 12, 4), e6b8d5b46647-12 (12, 13, 1) 2dc09a01254d-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2dc09a01254d-2 (3, 4, 2) - 42b07e8da27d-0 (7, 4, 4) [complete] - de561312eff4-0 (5, 2, 2), 42b07e8da27d-2 (7, 4, 2) + +485383494a89-8 (11, 12, 4) [complete] - f4b7da68b467-4 (9, 6, 2), 485383494a89-10 (11, 12, 2) + 42b07e8da27d-1 (7, 4, 3) [complete] - de561312eff4-1 (5, 2, 1), 42b07e8da27d-2 (7, 4, 2) -8aca7f8c9bd2-8 (10, 11, 3) [complete] - f4b7da68b467-4 (9, 6, 2), 8aca7f8c9bd2-10 (10, 11, 1) - +485383494a89-8 (11, 12, 4) [complete] - f4b7da68b467-4 (9, 6, 2), 485383494a89-10 (11, 12, 2) 2dc09a01254d-2 (3, 4, 2) [complete] - 01241442b3c2-2 (2, 3, 1), 2dc09a01254d-3 (3, 4, 1) 42b07e8da27d-2 (7, 4, 2) [complete] - b9bc20507e0b-2 (6, 3, 1), 42b07e8da27d-3 (7, 4, 1) +485383494a89-10 (11, 12, 2) [complete] - 8aca7f8c9bd2-10 (10, 11, 1), 485383494a89-11 (11, 12, 1) 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) - de561312eff4-0 (5, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), de561312eff4-1 (5, 2, 1) f4b7da68b467-4 (9, 6, 2) [complete] - 857477a9aebb-4 (8, 5, 1), f4b7da68b467-5 (9, 6, 1) - @@ -12,10 +14,12 @@ + 01241442b3c2-2 (2, 3, 1) [leaf] - 1ea73414a91b-0 (0, 1, 1) [leaf] - 2dc09a01254d-3 (3, 4, 1) [leaf] - 42b07e8da27d-3 (7, 4, 1) [leaf] - @@ -605,6 +637,23 @@ |/ o 0 1ea73414a91b r0 + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + fa942426a6fd 2 + 2b6d669947cd 4 + 4c748ffd1a46 3 + f0f3ef9a6cd5 4 + 2702dd0c91e7 5 + e7d9710d9fc6 5 + d62d843c9a01 6 + dcbb326fdec2 7 + ff43616e5d0f 7 + bab5d5bf48bd 5 + e46a4836065c 6 + b4594d867745 6 + 43227190fef8 5 + 1d8d22637c2d 8 $ hg debugstablerange --verify --verbose --subranges --rev 'head()' 1d8d22637c2d-0 (15, 8, 8) [complete] - 2b6d669947cd-0 (3, 4, 4), 1d8d22637c2d-4 (15, 8, 4) dcbb326fdec2-0 (9, 7, 7) [complete] - 2b6d669947cd-0 (3, 4, 4), dcbb326fdec2-4 (9, 7, 3) @@ -612,7 +661,7 @@ b4594d867745-0 (13, 6, 6) [complete] - 2b6d669947cd-0 (3, 4, 4), b4594d867745-4 (13, 6, 2) e46a4836065c-0 (12, 6, 6) [complete] - 2b6d669947cd-0 (3, 4, 4), e46a4836065c-4 (12, 6, 2) 2702dd0c91e7-0 (6, 5, 5) [complete] - f0f3ef9a6cd5-0 (5, 4, 4), 2702dd0c91e7-4 (6, 5, 1) - 1d8d22637c2d-4 (15, 8, 4) [complete] - 4c748ffd1a46-2 (4, 3, 1), 43227190fef8-4 (14, 5, 1), 1d8d22637c2d-6 (15, 8, 2) + 1d8d22637c2d-4 (15, 8, 4) [complete] - 43227190fef8-4 (14, 5, 1), 4c748ffd1a46-2 (4, 3, 1), 1d8d22637c2d-6 (15, 8, 2) 2b6d669947cd-0 (3, 4, 4) [complete] - 66f7d451a68b-0 (1, 2, 2), 2b6d669947cd-2 (3, 4, 2) f0f3ef9a6cd5-0 (5, 4, 4) [complete] - fa942426a6fd-0 (2, 2, 2), f0f3ef9a6cd5-2 (5, 4, 2) dcbb326fdec2-4 (9, 7, 3) [complete] - d62d843c9a01-4 (8, 6, 2), dcbb326fdec2-6 (9, 7, 1) @@ -664,10 +713,15 @@ |/ o 0 1ea73414a91b r0 + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + fa942426a6fd 2 + 36315563e2fa 3 + f37e476fba9a 5 $ hg debugstablerange --verify --verbose --subranges --rev 'head()' - f37e476fba9a-0 (4, 5, 5) [complete] - 66f7d451a68b-0 (1, 2, 2), 36315563e2fa-0 (3, 3, 3), f37e476fba9a-4 (4, 5, 1) + f37e476fba9a-0 (4, 5, 5) [complete] - 36315563e2fa-0 (3, 3, 3), 66f7d451a68b-1 (1, 2, 1), f37e476fba9a-4 (4, 5, 1) 36315563e2fa-0 (3, 3, 3) [complete] - fa942426a6fd-0 (2, 2, 2), 36315563e2fa-2 (3, 3, 1) - 66f7d451a68b-0 (1, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), 66f7d451a68b-1 (1, 2, 1) fa942426a6fd-0 (2, 2, 2) [complete] - 1ea73414a91b-0 (0, 1, 1), fa942426a6fd-1 (2, 2, 1) 1ea73414a91b-0 (0, 1, 1) [leaf] - 36315563e2fa-2 (3, 3, 1) [leaf] - diff -r 875de4816c5b -r bd99cb54712b tests/test-stablesort-branchpoint-criss-cross.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-stablesort-branchpoint-criss-cross.t Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,816 @@ +Test for stable ordering capabilities +===================================== + + $ . $TESTDIR/testlib/pythonpath.sh + + $ cat << EOF >> $HGRCPATH + > [extensions] + > hgext3rd.evolve = + > [ui] + > logtemplate = "{rev} {node|short} {desc} {tags}\n" + > [alias] + > showsort = debugstablesort --template="{node|short}\n" --method branchpoint + > EOF + + $ checktopo () { + > seen='null'; + > for node in `hg showsort --rev "$1"`; do + > echo "=== checking $node ==="; + > hg log --rev "($seen) and $node::"; + > seen="${seen}+${node}"; + > done; + > } + + $ cat << EOF >> random_rev.py + > import random + > import sys + > + > loop = int(sys.argv[1]) + > var = int(sys.argv[2]) + > for x in range(loop): + > print(x + random.randint(0, var)) + > EOF + +Check criss cross merge +======================= + + $ hg init crisscross_A + $ cd crisscross_A + $ hg debugbuilddag ' + > ...:base # create some base + > # criss cross #1: simple + > +3:AbaseA # "A" branch for CC "A" + > # criss cross #2:multiple closes ones + > .:BbaseA + > # criss cross #2:many branches + > ' + $ hg log -G + o 94 01f771406cab r94 Cfinal tip + |\ + | o 93 84d6ec6a8e21 r93 CmergeZB + | |\ + o | | 92 721ba7c5f4ff r92 CmergeZA + |\| | + | | o 91 8ae32c3ed670 r91 CmergeYC + | | |\ + | o \ \ 90 8b79544bb56d r90 CmergeYB + | |\ \ \ + o \ \ \ \ 89 041e1188f5f1 r89 CmergeYA + |\ \ \ \ \ + | o \ \ \ \ 88 2472d042ec95 r88 CmergeXF + | |\ \ \ \ \ + | | | | o \ \ 87 c7d3029bf731 r87 CmergeXE + | | | | |\ \ \ + | | | | | | | o 86 469c700e9ed8 r86 CmergeXD + | | | | | | | |\ + | | | | | | o \ \ 85 28be96b80dc1 r85 CmergeXC + | | | | | | |\ \ \ + | | | o \ \ \ \ \ \ 84 dbde319d43a3 r84 CmergeXB + | | | |\ \ \ \ \ \ \ + o | | | | | | | | | | 83 b3cf98c3d587 r83 CmergeXA + |\| | | | | | | | | | + | | | | | | o | | | | 82 1da228afcf06 r82 CmergeWK + | | | | | | |\ \ \ \ \ + | | | | | | +-+-------o 81 0bab31f71a21 r81 CmergeWJ + | | | | | | | | | | | + | | | | | | | | | o | 80 cd345198cf12 r80 CmergeWI + | | | | | | | | | |\ \ + | | | | o \ \ \ \ \ \ \ 79 82238c0bc950 r79 CmergeWH + | | | | |\ \ \ \ \ \ \ \ + o \ \ \ \ \ \ \ \ \ \ \ \ 78 89a0fe204177 r78 CmergeWG + |\ \ \ \ \ \ \ \ \ \ \ \ \ + | | | o \ \ \ \ \ \ \ \ \ \ 77 97d19fc5236f r77 CmergeWF + | | | |\ \ \ \ \ \ \ \ \ \ \ + | | | | | | | | o \ \ \ \ \ \ 76 37ad3ab0cddf r76 CmergeWE + | | | | | | | | |\ \ \ \ \ \ \ + | | | | | | | | | | | | | | | o 75 790cdfecd168 r75 CmergeWD + | | | | | | | | | | | | | | | |\ + | | | | | | | | | | | | o \ \ \ \ 74 698970a2480b r74 CmergeWC + | | | | | | | | | | | | |\ \ \ \ \ + | | | | | o \ \ \ \ \ \ \ \ \ \ \ \ 73 31d7b43cc321 r73 CmergeWB + | | | | | |\ \ \ \ \ \ \ \ \ \ \ \ \ + | | o \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ 72 eed373b0090d r72 CmergeWA + | | |\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ + | | | | | | | | | | | o \ \ \ \ \ \ \ \ 71 4f3b41956174 r71 CmergeT + | | | | | | | | | | | |\ \ \ \ \ \ \ \ \ + | | | | | o | | | | | | | | | | | | | | | 70 c3c7fa726f88 r70 CmergeS + | | | | | | | | | | | | | | | | | | | | | + | | | | | o-------------+ | | | | | | | | 69 d917f77a6439 r69 + | | | | | | | | | | | | | | | | | | | | | + | o | | | | | | | | | | | | | | | | | | | 68 fac9e582edd1 r68 CmergeR + | | | | | | | | | | | | | | | | | | | | | + | o | | | | | | | | | | | | | | | | | | | 67 e4cfd6264623 r67 + | | | | | | | | | | | | | | | | | | | | | + | o---------------------+ | | | | | | | | 66 d99e0f7dad5b r66 + | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | o-----+ | | | | | | | | 65 c713eae2d31f r65 CmergeQ + | | | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | +-+-----------o | | 64 b33fd5ad4c0c r64 CmergeP + | | | | | | | | | | | | | | | | | | / / + | | | | | +-----------+-----o | | | / / 63 bf6593f7e073 r63 CmergeO + | | | | | | | | | | | | | | / / / / / + | | | | | | | | | | | | | o | | | | | 62 3871506da61e r62 CmergeN + | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | o | | | | | 61 c84da74cf586 r61 + | | | | | | | | | | | | | | | | | | | + | | | | | | | | | | | | | o | | | | | 60 5eec91b12a58 r60 + | | | | | | | | | | | | | | | | | | | + | +-------------------+---o | | | | | 59 0484d39906c8 r59 + | | | | | | | | | | | | | / / / / / + | | | | | | | | | +---+-------o / / 58 29141354a762 r58 CmergeM + | | | | | | | | | | | | | | | / / + | | | | | | | | o | | | | | | | | 57 e7135b665740 r57 CmergeL + | | | | | | | | | | | | | | | | | + | | | | | | | | o | | | | | | | | 56 c7c1497fc270 r56 + | | | | | | | | | | | | | | | | | + | | | | | +-----o-------+ | | | | 55 76151e8066e1 r55 + | | | | | | | | / / / / / / / / + o | | | | | | | | | | | | | | | 54 9a67238ad1c4 r54 CmergeK + | | | | | | | | | | | | | | | | + o | | | | | | | | | | | | | | | 53 c37e7cd9f2bd r53 + | | | | | | | | | | | | | | | | + o | | | | | | | | | | | | | | | 52 0d153e3ad632 r52 + | | | | | | | | | | | | | | | | + o | | | | | | | | | | | | | | | 51 97ac964e34b7 r51 + | | | | | | | | | | | | | | | | + o | | | | | | | | | | | | | | | 50 900dd066a072 r50 + | | | | | | | | | | | | | | | | + o---------+---------+ | | | | | 49 673f5499c8c2 r49 + / / / / / / / / / / / / / / / + +-----o / / / / / / / / / / / 48 8ecb28746ec4 r48 CmergeJ + | | | |/ / / / / / / / / / / + | | | | | | | o | | | | | | 47 d6c9e2d27f14 r47 CmergeI + | | | | | | | | | | | | | | + | | | +-------o | | | | | | 46 bfcfd9a61e84 r46 + | | | | | | |/ / / / / / / + +---------------+-------o 45 40553f55397e r45 CmergeH + | | | | | | | | | | | | + | | o | | | | | | | | | 44 d94da36be176 r44 CmergeG + | | | | | | | | | | | | + +---o---------+ | | | | 43 4b39f229a0ce r43 + | | / / / / / / / / / + +---+---o / / / / / / 42 43fc0b77ff07 r42 CmergeF + | | | | / / / / / / + | | | | | | | | o | 41 88eace5ce682 r41 CmergeE + | | | | | | | | | | + | | | | | | | | o | 40 d928b4e8a515 r40 + | | | | | | | | | | + +-------+-------o | 39 88714f4125cb r39 + | | | | | | | | / + | | | | +---+---o 38 e3e6738c56ce r38 CmergeD + | | | | | | | | + | | | | | | | o 37 32b41ca704e1 r37 CmergeC + | | | | | | | | + | | | | +-+---o 36 01e29e20ea3f r36 + | | | | | | | + | | | o | | | 35 1f4a19f83a29 r35 CmergeB + | | |/|/ / / + | o | | | | 34 722d1b8b8942 r34 CmergeA + | | | | | | + | o | | | | 33 47c836a1f13e r33 + | | | | | | + | o | | | | 32 2ea3fbf151b5 r32 + | | | | | | + | o | | | | 31 0c3f2ba59eb7 r31 + | | | | | | + | o | | | | 30 f3441cd3e664 r30 + | | | | | | + | o | | | | 29 b9c3aa92fba5 r29 + | | | | | | + | o | | | | 28 3bdb00d5c818 r28 + | | | | | | + | o---+ | | 27 2bd677d0f13a r27 + |/ / / / / + | | | | o 26 de05b9c29ec7 r26 CbaseE + | | | | | + | | | o | 25 ad46a4a0fc10 r25 CbaseD + | | | | | + | | | o | 24 a457569c5306 r24 + | | | | | + | | | o | 23 f2bdd828a3aa r23 + | | | | | + | | | o | 22 5ce588c2b7c5 r22 + | | | | | + | | | o | 21 17b6e6bac221 r21 + | | | |/ + | o---+ 20 b115c694654e r20 CbaseC + | / / + o | | 19 884936b34999 r19 CbaseB + | | | + o---+ 18 9729470d9329 r18 + / / + o / 17 4f5078f7da8a r17 CbaseA + |/ + o 16 3e1560705803 r16 Bfinal + |\ + | o 15 55bf3fdb634f r15 BmergeD + | |\ + o---+ 14 39bab1cb1cbe r14 BmergeC + |/ / + | o 13 f7c6e7bfbcd0 r13 BmergeB + | |\ + o---+ 12 26f59ee8b1d7 r12 BmergeA + |/ / + | o 11 3e2da24aee59 r11 BbaseA + | | + | o 10 5ba9a53052ed r10 Afinal + |/| + o | 9 07c648efceeb r9 AmergeB BbaseB + |\ \ + +---o 8 c81423bf5a24 r8 AmergeA + | |/ + | o 7 65eb34ffc3a8 r7 AbaseB + | | + | o 6 0c1445abb33d r6 + | | + o | 5 c8d03c1b5e94 r5 AbaseA + | | + o | 4 bebd167eb94d r4 + | | + o | 3 2dc09a01254d r3 + |/ + o 2 01241442b3c2 r2 base + | + o 1 66f7d451a68b r1 + | + o 0 1ea73414a91b r0 + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + c8d03c1b5e94 6 + 0c1445abb33d 4 + 65eb34ffc3a8 5 + c81423bf5a24 9 + 07c648efceeb 9 + 5ba9a53052ed 11 + 3e2da24aee59 12 + 26f59ee8b1d7 13 + f7c6e7bfbcd0 13 + 39bab1cb1cbe 15 + 55bf3fdb634f 15 + 3e1560705803 17 + 4f5078f7da8a 18 + 9729470d9329 18 + 884936b34999 19 + b115c694654e 18 + 17b6e6bac221 18 + 5ce588c2b7c5 19 + f2bdd828a3aa 20 + a457569c5306 21 + ad46a4a0fc10 22 + de05b9c29ec7 18 + 2bd677d0f13a 21 + 3bdb00d5c818 22 + b9c3aa92fba5 23 + f3441cd3e664 24 + 0c3f2ba59eb7 25 + 2ea3fbf151b5 26 + 47c836a1f13e 27 + 722d1b8b8942 28 + 1f4a19f83a29 20 + 01e29e20ea3f 24 + 32b41ca704e1 25 + e3e6738c56ce 20 + 88714f4125cb 21 + d928b4e8a515 22 + 88eace5ce682 23 + 43fc0b77ff07 21 + 4b39f229a0ce 25 + d94da36be176 26 + 40553f55397e 21 + bfcfd9a61e84 20 + d6c9e2d27f14 21 + 8ecb28746ec4 21 + 673f5499c8c2 24 + 900dd066a072 25 + 97ac964e34b7 26 + 0d153e3ad632 27 + c37e7cd9f2bd 28 + 9a67238ad1c4 29 + 76151e8066e1 20 + c7c1497fc270 21 + e7135b665740 22 + 29141354a762 24 + 0484d39906c8 25 + 5eec91b12a58 26 + c84da74cf586 27 + 3871506da61e 28 + bf6593f7e073 24 + b33fd5ad4c0c 24 + c713eae2d31f 20 + d99e0f7dad5b 21 + e4cfd6264623 22 + fac9e582edd1 23 + d917f77a6439 20 + c3c7fa726f88 21 + 4f3b41956174 24 + eed373b0090d 36 + 31d7b43cc321 24 + 698970a2480b 31 + 790cdfecd168 24 + 37ad3ab0cddf 29 + 97d19fc5236f 25 + 89a0fe204177 36 + 82238c0bc950 25 + cd345198cf12 27 + 0bab31f71a21 31 + 1da228afcf06 31 + b3cf98c3d587 49 + dbde319d43a3 31 + 28be96b80dc1 36 + 469c700e9ed8 37 + c7d3029bf731 38 + 2472d042ec95 43 + 041e1188f5f1 55 + 8b79544bb56d 48 + 8ae32c3ed670 48 + 721ba7c5f4ff 77 + 84d6ec6a8e21 65 + 01f771406cab 95 + +Basic check +----------- + + $ hg showsort --rev 'Afinal' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 0c1445abb33d + 65eb34ffc3a8 + 2dc09a01254d + bebd167eb94d + c8d03c1b5e94 + 07c648efceeb + c81423bf5a24 + 5ba9a53052ed + $ checktopo Afinal + === checking 1ea73414a91b === + === checking 66f7d451a68b === + === checking 01241442b3c2 === + === checking 0c1445abb33d === + === checking 65eb34ffc3a8 === + === checking 2dc09a01254d === + === checking bebd167eb94d === + === checking c8d03c1b5e94 === + === checking 07c648efceeb === + === checking c81423bf5a24 === + === checking 5ba9a53052ed === + $ hg showsort --rev 'AmergeA' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 0c1445abb33d + 65eb34ffc3a8 + 2dc09a01254d + bebd167eb94d + c8d03c1b5e94 + c81423bf5a24 + $ checktopo AmergeA + === checking 1ea73414a91b === + === checking 66f7d451a68b === + === checking 01241442b3c2 === + === checking 0c1445abb33d === + === checking 65eb34ffc3a8 === + === checking 2dc09a01254d === + === checking bebd167eb94d === + === checking c8d03c1b5e94 === + === checking c81423bf5a24 === + $ hg showsort --rev 'AmergeB' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 0c1445abb33d + 65eb34ffc3a8 + 2dc09a01254d + bebd167eb94d + c8d03c1b5e94 + 07c648efceeb + $ checktopo AmergeB + === checking 1ea73414a91b === + === checking 66f7d451a68b === + === checking 01241442b3c2 === + === checking 0c1445abb33d === + === checking 65eb34ffc3a8 === + === checking 2dc09a01254d === + === checking bebd167eb94d === + === checking c8d03c1b5e94 === + === checking 07c648efceeb === + +close criss cross + $ hg showsort --rev 'Bfinal' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 0c1445abb33d + 65eb34ffc3a8 + 2dc09a01254d + bebd167eb94d + c8d03c1b5e94 + 07c648efceeb + c81423bf5a24 + 5ba9a53052ed + 3e2da24aee59 + 26f59ee8b1d7 + f7c6e7bfbcd0 + 39bab1cb1cbe + 55bf3fdb634f + 3e1560705803 + $ checktopo Bfinal + === checking 1ea73414a91b === + === checking 66f7d451a68b === + === checking 01241442b3c2 === + === checking 0c1445abb33d === + === checking 65eb34ffc3a8 === + === checking 2dc09a01254d === + === checking bebd167eb94d === + === checking c8d03c1b5e94 === + === checking 07c648efceeb === + === checking c81423bf5a24 === + === checking 5ba9a53052ed === + === checking 3e2da24aee59 === + === checking 26f59ee8b1d7 === + === checking f7c6e7bfbcd0 === + === checking 39bab1cb1cbe === + === checking 55bf3fdb634f === + === checking 3e1560705803 === + +many branches criss cross + + $ hg showsort --rev 'Cfinal' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 0c1445abb33d + 65eb34ffc3a8 + 2dc09a01254d + bebd167eb94d + c8d03c1b5e94 + 07c648efceeb + c81423bf5a24 + 5ba9a53052ed + 3e2da24aee59 + 26f59ee8b1d7 + f7c6e7bfbcd0 + 39bab1cb1cbe + 55bf3fdb634f + 3e1560705803 + 17b6e6bac221 + 5ce588c2b7c5 + f2bdd828a3aa + a457569c5306 + ad46a4a0fc10 + 4f5078f7da8a + 01e29e20ea3f + 32b41ca704e1 + 29141354a762 + 9729470d9329 + 884936b34999 + 0484d39906c8 + 5eec91b12a58 + c84da74cf586 + 3871506da61e + 2bd677d0f13a + 3bdb00d5c818 + b9c3aa92fba5 + f3441cd3e664 + 0c3f2ba59eb7 + 2ea3fbf151b5 + 47c836a1f13e + 722d1b8b8942 + 4b39f229a0ce + d94da36be176 + eed373b0090d + 88714f4125cb + d928b4e8a515 + 88eace5ce682 + 698970a2480b + b115c694654e + 1f4a19f83a29 + 43fc0b77ff07 + 31d7b43cc321 + 673f5499c8c2 + 900dd066a072 + 97ac964e34b7 + 0d153e3ad632 + c37e7cd9f2bd + 9a67238ad1c4 + 8ecb28746ec4 + bf6593f7e073 + 0bab31f71a21 + 1da228afcf06 + bfcfd9a61e84 + d6c9e2d27f14 + de05b9c29ec7 + 40553f55397e + 4f3b41956174 + 37ad3ab0cddf + c7d3029bf731 + 76151e8066e1 + c7c1497fc270 + e7135b665740 + b33fd5ad4c0c + cd345198cf12 + 28be96b80dc1 + c713eae2d31f + 82238c0bc950 + dbde319d43a3 + 8b79544bb56d + d917f77a6439 + c3c7fa726f88 + 97d19fc5236f + 2472d042ec95 + d99e0f7dad5b + e4cfd6264623 + fac9e582edd1 + 89a0fe204177 + b3cf98c3d587 + 041e1188f5f1 + 721ba7c5f4ff + e3e6738c56ce + 790cdfecd168 + 469c700e9ed8 + 8ae32c3ed670 + 84d6ec6a8e21 + 01f771406cab + $ checktopo Cfinal + === checking 1ea73414a91b === + === checking 66f7d451a68b === + === checking 01241442b3c2 === + === checking 0c1445abb33d === + === checking 65eb34ffc3a8 === + === checking 2dc09a01254d === + === checking bebd167eb94d === + === checking c8d03c1b5e94 === + === checking 07c648efceeb === + === checking c81423bf5a24 === + === checking 5ba9a53052ed === + === checking 3e2da24aee59 === + === checking 26f59ee8b1d7 === + === checking f7c6e7bfbcd0 === + === checking 39bab1cb1cbe === + === checking 55bf3fdb634f === + === checking 3e1560705803 === + === checking 17b6e6bac221 === + === checking 5ce588c2b7c5 === + === checking f2bdd828a3aa === + === checking a457569c5306 === + === checking ad46a4a0fc10 === + === checking 4f5078f7da8a === + === checking 01e29e20ea3f === + === checking 32b41ca704e1 === + === checking 29141354a762 === + === checking 9729470d9329 === + === checking 884936b34999 === + === checking 0484d39906c8 === + === checking 5eec91b12a58 === + === checking c84da74cf586 === + === checking 3871506da61e === + === checking 2bd677d0f13a === + === checking 3bdb00d5c818 === + === checking b9c3aa92fba5 === + === checking f3441cd3e664 === + === checking 0c3f2ba59eb7 === + === checking 2ea3fbf151b5 === + === checking 47c836a1f13e === + === checking 722d1b8b8942 === + === checking 4b39f229a0ce === + === checking d94da36be176 === + === checking eed373b0090d === + === checking 88714f4125cb === + === checking d928b4e8a515 === + === checking 88eace5ce682 === + === checking 698970a2480b === + === checking b115c694654e === + === checking 1f4a19f83a29 === + === checking 43fc0b77ff07 === + === checking 31d7b43cc321 === + === checking 673f5499c8c2 === + === checking 900dd066a072 === + === checking 97ac964e34b7 === + === checking 0d153e3ad632 === + === checking c37e7cd9f2bd === + === checking 9a67238ad1c4 === + === checking 8ecb28746ec4 === + === checking bf6593f7e073 === + === checking 0bab31f71a21 === + === checking 1da228afcf06 === + === checking bfcfd9a61e84 === + === checking d6c9e2d27f14 === + === checking de05b9c29ec7 === + === checking 40553f55397e === + === checking 4f3b41956174 === + === checking 37ad3ab0cddf === + === checking c7d3029bf731 === + === checking 76151e8066e1 === + === checking c7c1497fc270 === + === checking e7135b665740 === + === checking b33fd5ad4c0c === + === checking cd345198cf12 === + === checking 28be96b80dc1 === + === checking c713eae2d31f === + === checking 82238c0bc950 === + === checking dbde319d43a3 === + === checking 8b79544bb56d === + === checking d917f77a6439 === + === checking c3c7fa726f88 === + === checking 97d19fc5236f === + === checking 2472d042ec95 === + === checking d99e0f7dad5b === + === checking e4cfd6264623 === + === checking fac9e582edd1 === + === checking 89a0fe204177 === + === checking b3cf98c3d587 === + === checking 041e1188f5f1 === + === checking 721ba7c5f4ff === + === checking e3e6738c56ce === + === checking 790cdfecd168 === + === checking 469c700e9ed8 === + === checking 8ae32c3ed670 === + === checking 84d6ec6a8e21 === + === checking 01f771406cab === + +Test stability of this mess +--------------------------- + + $ hg log -r tip + 94 01f771406cab r94 Cfinal tip + $ hg showsort --rev 'all()' > ../crisscross.source.order + $ cd .. + + $ hg clone crisscross_A crisscross_random --rev 0 + adding changesets + adding manifests + adding file changes + added 1 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd crisscross_random + $ for x in `python ../random_rev.py 50 44`; do + > # using python to benefit from the random seed + > hg pull -r $x --quiet + > done; + $ hg pull --quiet + + $ hg showsort --rev 'all()' > ../crisscross.random.order + $ python "$RUNTESTDIR/md5sum.py" ../crisscross.*.order + d9aab0d1907d5cf64d205a8b9036e959 ../crisscross.random.order + d9aab0d1907d5cf64d205a8b9036e959 ../crisscross.source.order + $ diff -u ../crisscross.*.order + $ hg showsort --rev 'all()' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 0c1445abb33d + 65eb34ffc3a8 + 2dc09a01254d + bebd167eb94d + c8d03c1b5e94 + 07c648efceeb + c81423bf5a24 + 5ba9a53052ed + 3e2da24aee59 + 26f59ee8b1d7 + f7c6e7bfbcd0 + 39bab1cb1cbe + 55bf3fdb634f + 3e1560705803 + 17b6e6bac221 + 5ce588c2b7c5 + f2bdd828a3aa + a457569c5306 + ad46a4a0fc10 + 4f5078f7da8a + 01e29e20ea3f + 32b41ca704e1 + 29141354a762 + 9729470d9329 + 884936b34999 + 0484d39906c8 + 5eec91b12a58 + c84da74cf586 + 3871506da61e + 2bd677d0f13a + 3bdb00d5c818 + b9c3aa92fba5 + f3441cd3e664 + 0c3f2ba59eb7 + 2ea3fbf151b5 + 47c836a1f13e + 722d1b8b8942 + 4b39f229a0ce + d94da36be176 + eed373b0090d + 88714f4125cb + d928b4e8a515 + 88eace5ce682 + 698970a2480b + b115c694654e + 1f4a19f83a29 + 43fc0b77ff07 + 31d7b43cc321 + 673f5499c8c2 + 900dd066a072 + 97ac964e34b7 + 0d153e3ad632 + c37e7cd9f2bd + 9a67238ad1c4 + 8ecb28746ec4 + bf6593f7e073 + 0bab31f71a21 + 1da228afcf06 + bfcfd9a61e84 + d6c9e2d27f14 + de05b9c29ec7 + 40553f55397e + 4f3b41956174 + 37ad3ab0cddf + c7d3029bf731 + 76151e8066e1 + c7c1497fc270 + e7135b665740 + b33fd5ad4c0c + cd345198cf12 + 28be96b80dc1 + c713eae2d31f + 82238c0bc950 + dbde319d43a3 + 8b79544bb56d + d917f77a6439 + c3c7fa726f88 + 97d19fc5236f + 2472d042ec95 + d99e0f7dad5b + e4cfd6264623 + fac9e582edd1 + 89a0fe204177 + b3cf98c3d587 + 041e1188f5f1 + 721ba7c5f4ff + e3e6738c56ce + 790cdfecd168 + 469c700e9ed8 + 8ae32c3ed670 + 84d6ec6a8e21 + 01f771406cab diff -r 875de4816c5b -r bd99cb54712b tests/test-stablesort-branchpoint.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-stablesort-branchpoint.t Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,846 @@ +Test for stable ordering capabilities +===================================== + + $ . $TESTDIR/testlib/pythonpath.sh + + $ cat << EOF >> $HGRCPATH + > [extensions] + > hgext3rd.evolve = + > [ui] + > logtemplate = "{rev} {node|short} {desc} {tags}\n" + > [alias] + > showsort = debugstablesort --template="{node|short}\n" --method branchpoint + > EOF + + + + $ checktopo () { + > seen='null'; + > for node in `hg showsort --rev "$1"`; do + > echo "=== checking $node ==="; + > hg log --rev "($seen) and $node::"; + > seen="${seen}+${node}"; + > done; + > } + + $ cat << EOF >> random_rev.py + > import random + > import sys + > + > loop = int(sys.argv[1]) + > var = int(sys.argv[2]) + > for x in range(loop): + > print(x + random.randint(0, var)) + > EOF + +Basic tests +=========== +(no criss cross merge) + +Smoke tests +----------- + +Starts with a "simple case" + + $ hg init repo_A + $ cd repo_A + $ hg debugbuilddag ' + > ..:g # 2 nodes, tagged "g" + > <2.:h # another node base one -2 -> 0, tagged "h" + > *1/2:m # merge -1 and -2 (1, 2), tagged "m" + > <2+2:i # 2 nodes based on -2, tag head as "i" + > .:c # 1 node tagged "c" + > <2.:b # 1 node based on -2; tagged "b" + > <2.:e # 1 node based on -2, tagged "e" + > ' + $ hg log -G + o 15 1d8d22637c2d r15 tip + |\ + | o 14 43227190fef8 r14 f + | | + | | o 13 b4594d867745 r13 e + | | | + | | | o 12 e46a4836065c r12 d + | | |/ + | | o 11 bab5d5bf48bd r11 + | |/ + | | o 10 ff43616e5d0f r10 b + | | | + | | | o 9 dcbb326fdec2 r9 a + | | |/ + | | o 8 d62d843c9a01 r8 + | | | + | | o 7 e7d9710d9fc6 r7 + | |/ + +---o 6 2702dd0c91e7 r6 c + | | + o | 5 f0f3ef9a6cd5 r5 i + | | + o | 4 4c748ffd1a46 r4 + | | + | o 3 2b6d669947cd r3 m + |/| + o | 2 fa942426a6fd r2 h + | | + | o 1 66f7d451a68b r1 g + |/ + o 0 1ea73414a91b r0 + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + fa942426a6fd 2 + 2b6d669947cd 4 + 4c748ffd1a46 3 + f0f3ef9a6cd5 4 + 2702dd0c91e7 5 + e7d9710d9fc6 5 + d62d843c9a01 6 + dcbb326fdec2 7 + ff43616e5d0f 7 + bab5d5bf48bd 5 + e46a4836065c 6 + b4594d867745 6 + 43227190fef8 5 + 1d8d22637c2d 8 + $ hg showsort --rev 'all()' --traceback + 1ea73414a91b + 66f7d451a68b + fa942426a6fd + 2b6d669947cd + 43227190fef8 + bab5d5bf48bd + b4594d867745 + e46a4836065c + e7d9710d9fc6 + d62d843c9a01 + dcbb326fdec2 + ff43616e5d0f + 4c748ffd1a46 + f0f3ef9a6cd5 + 1d8d22637c2d + 2702dd0c91e7 + +Verify the topological order +---------------------------- + +Check we we did not issued a node before on ancestor + +output of log should be empty + + $ checktopo 'all()' + === checking 1ea73414a91b === + === checking 66f7d451a68b === + === checking fa942426a6fd === + === checking 2b6d669947cd === + === checking 43227190fef8 === + === checking bab5d5bf48bd === + === checking b4594d867745 === + === checking e46a4836065c === + === checking e7d9710d9fc6 === + === checking d62d843c9a01 === + === checking dcbb326fdec2 === + === checking ff43616e5d0f === + === checking 4c748ffd1a46 === + === checking f0f3ef9a6cd5 === + === checking 1d8d22637c2d === + === checking 2702dd0c91e7 === + +Check stability +=============== + +have repo with changesets in orders + + $ cd .. + $ hg -R repo_A log -G > A.log + $ hg clone repo_A repo_B --rev 5 + adding changesets + adding manifests + adding file changes + added 4 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg -R repo_B pull --rev 13 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg -R repo_B pull --rev 14 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads .' to see heads, 'hg merge' to merge) + $ hg -R repo_B pull + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 7 changesets with 0 changes to 0 files (+3 heads) + (run 'hg heads .' to see heads, 'hg merge' to merge) + $ hg -R repo_B log -G + o 15 1d8d22637c2d r15 tip + |\ + | | o 14 e46a4836065c r12 + | | | + | | | o 13 ff43616e5d0f r10 + | | | | + | | | | o 12 dcbb326fdec2 r9 + | | | |/ + | | | o 11 d62d843c9a01 r8 + | | | | + | | | o 10 e7d9710d9fc6 r7 + | | | | + +-------o 9 2702dd0c91e7 r6 + | | | | + | o---+ 8 43227190fef8 r14 + | / / + | +---o 7 b4594d867745 r13 + | | | + | o | 6 bab5d5bf48bd r11 + | |/ + | o 5 2b6d669947cd r3 + | |\ + | | o 4 66f7d451a68b r1 + | | | + @ | | 3 f0f3ef9a6cd5 r5 + | | | + o | | 2 4c748ffd1a46 r4 + |/ / + o / 1 fa942426a6fd r2 + |/ + o 0 1ea73414a91b r0 + + $ hg -R repo_B debugdepth -r 'all()' + 1ea73414a91b 1 + fa942426a6fd 2 + 4c748ffd1a46 3 + f0f3ef9a6cd5 4 + 66f7d451a68b 2 + 2b6d669947cd 4 + bab5d5bf48bd 5 + b4594d867745 6 + 43227190fef8 5 + 2702dd0c91e7 5 + e7d9710d9fc6 5 + d62d843c9a01 6 + dcbb326fdec2 7 + ff43616e5d0f 7 + e46a4836065c 6 + 1d8d22637c2d 8 + $ hg -R repo_B log -G > B.log + + $ hg clone repo_A repo_C --rev 10 + adding changesets + adding manifests + adding file changes + added 7 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg -R repo_C pull --rev 12 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg -R repo_C pull --rev 15 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads .' to see heads, 'hg merge' to merge) + $ hg -R repo_C pull + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 3 changesets with 0 changes to 0 files (+3 heads) + (run 'hg heads .' to see heads, 'hg merge' to merge) + $ hg -R repo_C log -G + o 15 b4594d867745 r13 tip + | + | o 14 dcbb326fdec2 r9 + | | + | | o 13 2702dd0c91e7 r6 + | | | + | | | o 12 1d8d22637c2d r15 + | | |/| + | | | o 11 43227190fef8 r14 + | | | | + | | o | 10 f0f3ef9a6cd5 r5 + | | | | + | | o | 9 4c748ffd1a46 r4 + | | | | + +-------o 8 e46a4836065c r12 + | | | | + o-----+ 7 bab5d5bf48bd r11 + / / / + +-----@ 6 ff43616e5d0f r10 + | | | + o | | 5 d62d843c9a01 r8 + | | | + o---+ 4 e7d9710d9fc6 r7 + / / + | o 3 2b6d669947cd r3 + |/| + o | 2 fa942426a6fd r2 + | | + | o 1 66f7d451a68b r1 + |/ + o 0 1ea73414a91b r0 + + $ hg -R repo_C log -G > C.log + + $ hg clone repo_A repo_D --rev 2 + adding changesets + adding manifests + adding file changes + added 2 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg -R repo_D pull --rev 10 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 5 changesets with 0 changes to 0 files + (run 'hg update' to get a working copy) + $ hg -R repo_D pull --rev 15 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg -R repo_D pull + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 5 changesets with 0 changes to 0 files (+4 heads) + (run 'hg heads .' to see heads, 'hg merge' to merge) + $ hg -R repo_D log -G + o 15 b4594d867745 r13 tip + | + | o 14 e46a4836065c r12 + |/ + o 13 bab5d5bf48bd r11 + | + | o 12 dcbb326fdec2 r9 + | | + | | o 11 2702dd0c91e7 r6 + | | | + | | | o 10 1d8d22637c2d r15 + | | |/| + +-----o 9 43227190fef8 r14 + | | | + | | o 8 f0f3ef9a6cd5 r5 + | | | + | | o 7 4c748ffd1a46 r4 + | | | + | +---o 6 ff43616e5d0f r10 + | | | + | o | 5 d62d843c9a01 r8 + | | | + | o | 4 e7d9710d9fc6 r7 + |/ / + o | 3 2b6d669947cd r3 + |\| + o | 2 66f7d451a68b r1 + | | + | @ 1 fa942426a6fd r2 + |/ + o 0 1ea73414a91b r0 + + $ hg -R repo_D log -G > D.log + +check the log output are different + + $ python "$RUNTESTDIR/md5sum.py" *.log + 55919ebc9c02f28070cf3255b1690f8c A.log + c6244b76a60d0707767dc71780e544f3 B.log + 4d8b08b8c50ecbdd2460a62e5852d84d C.log + 0f327003593b50b9591bea8ee28acb81 D.log + +bug stable ordering should be identical +--------------------------------------- + + $ repos="A B C D " + +for 'all()' + + $ for x in $repos; do + > echo $x + > hg -R repo_$x showsort --rev 'all()' > ${x}.all.order; + > done + A + B + C + D + + $ python "$RUNTESTDIR/md5sum.py" *.all.order + 0c6b2e6f15249c0359b0f93e28c5bd1c A.all.order + 0c6b2e6f15249c0359b0f93e28c5bd1c B.all.order + 0c6b2e6f15249c0359b0f93e28c5bd1c C.all.order + 0c6b2e6f15249c0359b0f93e28c5bd1c D.all.order + +one specific head + + $ for x in $repos; do + > hg -R repo_$x showsort --rev 'b4594d867745' > ${x}.b4594d867745.order; + > done + + $ python "$RUNTESTDIR/md5sum.py" *.b4594d867745.order + 5c40900a22008f24eab8dfe2f30ad79f A.b4594d867745.order + 5c40900a22008f24eab8dfe2f30ad79f B.b4594d867745.order + 5c40900a22008f24eab8dfe2f30ad79f C.b4594d867745.order + 5c40900a22008f24eab8dfe2f30ad79f D.b4594d867745.order + +one secific heads, that is a merge + + $ for x in $repos; do + > hg -R repo_$x showsort --rev '1d8d22637c2d' > ${x}.1d8d22637c2d.order; + > done + + $ python "$RUNTESTDIR/md5sum.py" *.1d8d22637c2d.order + 77dc20a6f86db9103df8edaae9ad2754 A.1d8d22637c2d.order + 77dc20a6f86db9103df8edaae9ad2754 B.1d8d22637c2d.order + 77dc20a6f86db9103df8edaae9ad2754 C.1d8d22637c2d.order + 77dc20a6f86db9103df8edaae9ad2754 D.1d8d22637c2d.order + +changeset that are not heads + + $ for x in $repos; do + > hg -R repo_$x showsort --rev 'e7d9710d9fc6+43227190fef8' > ${x}.non-heads.order; + > done + + $ python "$RUNTESTDIR/md5sum.py" *.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 A.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 B.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 C.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 D.non-heads.order + +Check with different subset + + $ hg clone repo_A repo_E --rev "43227190fef8" + adding changesets + adding manifests + adding file changes + added 5 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg -R repo_E pull --rev e7d9710d9fc6 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + + $ hg clone repo_A repo_F --rev "1d8d22637c2d" + adding changesets + adding manifests + adding file changes + added 8 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg -R repo_F pull --rev d62d843c9a01 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 2 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + + $ hg clone repo_A repo_G --rev "e7d9710d9fc6" + adding changesets + adding manifests + adding file changes + added 5 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg -R repo_G pull --rev 43227190fef8 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hg -R repo_G pull --rev 2702dd0c91e7 + pulling from $TESTTMP/repo_A (glob) + searching for changes + adding changesets + adding manifests + adding file changes + added 3 changesets with 0 changes to 0 files (+1 heads) + (run 'hg heads .' to see heads, 'hg merge' to merge) + + $ for x in E F G; do + > hg -R repo_$x showsort --rev 'e7d9710d9fc6+43227190fef8' > ${x}.non-heads.order; + > done + + $ python "$RUNTESTDIR/md5sum.py" *.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 A.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 B.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 C.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 D.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 E.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 F.non-heads.order + 94e0ea8cdade135dabde4ec5e9954329 G.non-heads.order + +Multiple recursions +=================== + + $ hg init recursion_A + $ cd recursion_A + $ hg debugbuilddag ' + > .:base + > +3:A + > +2/A:C + > +3:F + > +2 + > ' + $ hg log -G + o 20 160a7a0adbf4 r20 tip + | + o 19 1c645e73dbc6 r19 + | + o 18 0496f0a6a143 r18 + |\ + | o 17 d64d500024d1 r17 + | | + | o 16 4dbf739dd63f r16 + | | + | o 15 9fff0871d230 r15 + | | + | | o 14 4bbfc6078919 r14 F + | | | + | | o 13 013b27f11536 r13 + | | | + +---o 12 a66b68853635 r12 + | | + o | 11 001194dd78d5 r11 E + |\ \ + | o | 10 6ee532b68cfa r10 + | | | + o | | 9 529dfc5bb875 r9 D + | | | + o | | 8 abf57d94268b r8 + | | | + +---o 7 5f18015f9110 r7 C + | | | + | | o 6 a2f58e9c1e56 r6 + | | | + | | o 5 3a367db1fabc r5 + | |/ + | o 4 e7bd5218ca15 r4 B + | | + o | 3 2dc09a01254d r3 A + | | + o | 2 01241442b3c2 r2 + | | + o | 1 66f7d451a68b r1 + |/ + o 0 1ea73414a91b r0 base + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + e7bd5218ca15 2 + 3a367db1fabc 3 + a2f58e9c1e56 4 + 5f18015f9110 8 + abf57d94268b 5 + 529dfc5bb875 6 + 6ee532b68cfa 3 + 001194dd78d5 9 + a66b68853635 10 + 013b27f11536 11 + 4bbfc6078919 12 + 9fff0871d230 9 + 4dbf739dd63f 10 + d64d500024d1 11 + 0496f0a6a143 16 + 1c645e73dbc6 17 + 160a7a0adbf4 18 + $ hg showsort --rev 'all()' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + abf57d94268b + 529dfc5bb875 + e7bd5218ca15 + 3a367db1fabc + a2f58e9c1e56 + 5f18015f9110 + 9fff0871d230 + 4dbf739dd63f + d64d500024d1 + 6ee532b68cfa + 001194dd78d5 + 0496f0a6a143 + 1c645e73dbc6 + 160a7a0adbf4 + a66b68853635 + 013b27f11536 + 4bbfc6078919 + $ checktopo 'all()' + === checking 1ea73414a91b === + === checking 66f7d451a68b === + === checking 01241442b3c2 === + === checking 2dc09a01254d === + === checking abf57d94268b === + === checking 529dfc5bb875 === + === checking e7bd5218ca15 === + === checking 3a367db1fabc === + === checking a2f58e9c1e56 === + === checking 5f18015f9110 === + === checking 9fff0871d230 === + === checking 4dbf739dd63f === + === checking d64d500024d1 === + === checking 6ee532b68cfa === + === checking 001194dd78d5 === + === checking 0496f0a6a143 === + === checking 1c645e73dbc6 === + === checking 160a7a0adbf4 === + === checking a66b68853635 === + === checking 013b27f11536 === + === checking 4bbfc6078919 === + $ hg showsort --rev 'all()' > ../multiple.source.order + $ hg log -r tip + 20 160a7a0adbf4 r20 tip + $ cd .. + + $ hg clone recursion_A recursion_random --rev 0 + adding changesets + adding manifests + adding file changes + added 1 changesets with 0 changes to 0 files + updating to branch default + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd recursion_random + $ for x in `python ../random_rev.py 15 5`; do + > # using python to benefit from the random seed + > hg pull -r $x --quiet + > done; + $ hg pull --quiet + $ hg showsort --rev 'all()' > ../multiple.random.order + $ python "$RUNTESTDIR/md5sum.py" ../multiple.*.order + 6ff802a0a5f0a3ddd82b25f860238fbd ../multiple.random.order + 6ff802a0a5f0a3ddd82b25f860238fbd ../multiple.source.order + $ hg showsort --rev 'all()' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + abf57d94268b + 529dfc5bb875 + e7bd5218ca15 + 3a367db1fabc + a2f58e9c1e56 + 5f18015f9110 + 9fff0871d230 + 4dbf739dd63f + d64d500024d1 + 6ee532b68cfa + 001194dd78d5 + 0496f0a6a143 + 1c645e73dbc6 + 160a7a0adbf4 + a66b68853635 + 013b27f11536 + 4bbfc6078919 + $ cd .. + + +Test behavior with oedipus merges +================================= + + $ hg init recursion_oedipus + $ cd recursion_oedipus + $ echo base > base + $ hg add base + $ hg ci -m base + $ hg branch foo + marked working directory as branch foo + (branches are permanent and global, did you want a bookmark?) + $ echo foo1 > foo1 + $ hg add foo1 + $ hg ci -m foo1 + $ echo foo2 > foo2 + $ hg add foo2 + $ hg ci -m foo2 + $ hg up default + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + $ hg merge foo + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m oedipus_merge + $ echo default1 > default1 + $ hg add default1 + $ hg ci -m default1 + $ hg log -G + @ 4 7f2454f6b04f default1 tip + | + o 3 ed776db7ed63 oedipus_merge + |\ + | o 2 0dedbcd995b6 foo2 + | | + | o 1 47da0f2c25e2 foo1 + |/ + o 0 d20a80d4def3 base + + $ hg debugdepth -r 'all()' + d20a80d4def3 1 + 47da0f2c25e2 2 + 0dedbcd995b6 3 + ed776db7ed63 4 + 7f2454f6b04f 5 + $ hg showsort --rev '.' + d20a80d4def3 + 47da0f2c25e2 + 0dedbcd995b6 + ed776db7ed63 + 7f2454f6b04f + +Merge two branches with their own independant internal merge. +------------------------------------------------------------- + + $ hg init subbranch + $ cd subbranch + $ hg debugbuilddag ' + > .:base + > +3:leftBranch + > +2:leftA + > /leftA:leftMerge + > +4:rightA + > /rightA:rightMerge + > +3/leftMerge + > ' + $ hg log -G + o 22 56526aefbff4 r22 tip + |\ + | o 21 d4422659bc40 r21 + | | + | o 20 6a97ef856f90 r20 + | | + | o 19 5648bbf0e38b r19 + | | + | o 18 4442c125b80d r18 rightMerge + | |\ + | | o 17 65e683dd6db4 r17 rightB + | | | + | | o 16 5188cf52b7b7 r16 + | | | + | o | 15 191bac7bf37c r15 rightA + | | | + | o | 14 5cb8e6902ff3 r14 + | | | + | o | 13 448a7ac3ab1f r13 + | | | + | o | 12 ee222cc71ce6 r12 + | |/ + | o 11 e5c0d969abc4 r11 rightBranch + | | + | o 10 7cc044fdf4a7 r10 + | | + o | 9 9f6c364a3574 r9 leftMerge + |\ \ + | o | 8 588f0bc87ecd r8 leftB + | | | + | o | 7 e2317cea05f7 r7 + | | | + | o | 6 c2c595bcd4c6 r6 + | | | + o | | 5 c8d03c1b5e94 r5 leftA + | | | + o | | 4 bebd167eb94d r4 + |/ / + o | 3 2dc09a01254d r3 leftBranch + | | + o | 2 01241442b3c2 r2 + | | + o | 1 66f7d451a68b r1 + |/ + o 0 1ea73414a91b r0 base + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + c8d03c1b5e94 6 + c2c595bcd4c6 5 + e2317cea05f7 6 + 588f0bc87ecd 7 + 9f6c364a3574 10 + 7cc044fdf4a7 2 + e5c0d969abc4 3 + ee222cc71ce6 4 + 448a7ac3ab1f 5 + 5cb8e6902ff3 6 + 191bac7bf37c 7 + 5188cf52b7b7 4 + 65e683dd6db4 5 + 4442c125b80d 10 + 5648bbf0e38b 11 + 6a97ef856f90 12 + d4422659bc40 13 + 56526aefbff4 23 + $ hg showsort --rev 'tip' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + bebd167eb94d + c8d03c1b5e94 + c2c595bcd4c6 + e2317cea05f7 + 588f0bc87ecd + 9f6c364a3574 + 7cc044fdf4a7 + e5c0d969abc4 + 5188cf52b7b7 + 65e683dd6db4 + ee222cc71ce6 + 448a7ac3ab1f + 5cb8e6902ff3 + 191bac7bf37c + 4442c125b80d + 5648bbf0e38b + 6a97ef856f90 + d4422659bc40 + 56526aefbff4 + $ cd .. diff -r 875de4816c5b -r bd99cb54712b tests/test-stablesort-criss-cross.t --- a/tests/test-stablesort-criss-cross.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-stablesort-criss-cross.t Mon Dec 11 18:30:15 2017 +0100 @@ -9,7 +9,7 @@ > [ui] > logtemplate = "{rev} {node|short} {desc} {tags}\n" > [alias] - > showsort = debugstablesort --template="{node|short}\n" + > showsort = debugstablesort --template="{node|short}\n" --method headcached > EOF $ checktopo () { @@ -293,6 +293,102 @@ | o 0 1ea73414a91b r0 + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + c8d03c1b5e94 6 + 0c1445abb33d 4 + 65eb34ffc3a8 5 + c81423bf5a24 9 + 07c648efceeb 9 + 5ba9a53052ed 11 + 3e2da24aee59 12 + 26f59ee8b1d7 13 + f7c6e7bfbcd0 13 + 39bab1cb1cbe 15 + 55bf3fdb634f 15 + 3e1560705803 17 + 4f5078f7da8a 18 + 9729470d9329 18 + 884936b34999 19 + b115c694654e 18 + 17b6e6bac221 18 + 5ce588c2b7c5 19 + f2bdd828a3aa 20 + a457569c5306 21 + ad46a4a0fc10 22 + de05b9c29ec7 18 + 2bd677d0f13a 21 + 3bdb00d5c818 22 + b9c3aa92fba5 23 + f3441cd3e664 24 + 0c3f2ba59eb7 25 + 2ea3fbf151b5 26 + 47c836a1f13e 27 + 722d1b8b8942 28 + 1f4a19f83a29 20 + 01e29e20ea3f 24 + 32b41ca704e1 25 + e3e6738c56ce 20 + 88714f4125cb 21 + d928b4e8a515 22 + 88eace5ce682 23 + 43fc0b77ff07 21 + 4b39f229a0ce 25 + d94da36be176 26 + 40553f55397e 21 + bfcfd9a61e84 20 + d6c9e2d27f14 21 + 8ecb28746ec4 21 + 673f5499c8c2 24 + 900dd066a072 25 + 97ac964e34b7 26 + 0d153e3ad632 27 + c37e7cd9f2bd 28 + 9a67238ad1c4 29 + 76151e8066e1 20 + c7c1497fc270 21 + e7135b665740 22 + 29141354a762 24 + 0484d39906c8 25 + 5eec91b12a58 26 + c84da74cf586 27 + 3871506da61e 28 + bf6593f7e073 24 + b33fd5ad4c0c 24 + c713eae2d31f 20 + d99e0f7dad5b 21 + e4cfd6264623 22 + fac9e582edd1 23 + d917f77a6439 20 + c3c7fa726f88 21 + 4f3b41956174 24 + eed373b0090d 36 + 31d7b43cc321 24 + 698970a2480b 31 + 790cdfecd168 24 + 37ad3ab0cddf 29 + 97d19fc5236f 25 + 89a0fe204177 36 + 82238c0bc950 25 + cd345198cf12 27 + 0bab31f71a21 31 + 1da228afcf06 31 + b3cf98c3d587 49 + dbde319d43a3 31 + 28be96b80dc1 36 + 469c700e9ed8 37 + c7d3029bf731 38 + 2472d042ec95 43 + 041e1188f5f1 55 + 8b79544bb56d 48 + 8ae32c3ed670 48 + 721ba7c5f4ff 77 + 84d6ec6a8e21 65 + 01f771406cab 95 Basic check ----------- @@ -420,21 +516,15 @@ 39bab1cb1cbe 55bf3fdb634f 3e1560705803 - 17b6e6bac221 - 5ce588c2b7c5 - f2bdd828a3aa - a457569c5306 - ad46a4a0fc10 - 4f5078f7da8a - 01e29e20ea3f - 32b41ca704e1 - 29141354a762 9729470d9329 884936b34999 - 0484d39906c8 - 5eec91b12a58 - c84da74cf586 - 3871506da61e + b115c694654e + 8ecb28746ec4 + de05b9c29ec7 + d917f77a6439 + c3c7fa726f88 + 97d19fc5236f + 4f5078f7da8a 2bd677d0f13a 3bdb00d5c818 b9c3aa92fba5 @@ -443,55 +533,61 @@ 2ea3fbf151b5 47c836a1f13e 722d1b8b8942 + 17b6e6bac221 + 5ce588c2b7c5 + f2bdd828a3aa + a457569c5306 + ad46a4a0fc10 4b39f229a0ce d94da36be176 eed373b0090d - 88714f4125cb - d928b4e8a515 - 88eace5ce682 - 698970a2480b - b115c694654e - 1f4a19f83a29 - 43fc0b77ff07 - 31d7b43cc321 + 2472d042ec95 673f5499c8c2 900dd066a072 97ac964e34b7 0d153e3ad632 c37e7cd9f2bd 9a67238ad1c4 - 8ecb28746ec4 - bf6593f7e073 - 0bab31f71a21 - 1da228afcf06 - bfcfd9a61e84 - d6c9e2d27f14 - de05b9c29ec7 - 40553f55397e - 4f3b41956174 - 37ad3ab0cddf - c7d3029bf731 - 76151e8066e1 - c7c1497fc270 - e7135b665740 - b33fd5ad4c0c - cd345198cf12 - 28be96b80dc1 - c713eae2d31f - 82238c0bc950 - dbde319d43a3 - 8b79544bb56d - d917f77a6439 - c3c7fa726f88 - 97d19fc5236f - 2472d042ec95 d99e0f7dad5b e4cfd6264623 fac9e582edd1 89a0fe204177 b3cf98c3d587 041e1188f5f1 + 0484d39906c8 + 5eec91b12a58 + c84da74cf586 + 3871506da61e + bf6593f7e073 + 1da228afcf06 + 4f3b41956174 + bfcfd9a61e84 + d6c9e2d27f14 + 37ad3ab0cddf + c7d3029bf731 + 1f4a19f83a29 + 43fc0b77ff07 + 31d7b43cc321 + c713eae2d31f + 76151e8066e1 + c7c1497fc270 + e7135b665740 + 82238c0bc950 + dbde319d43a3 + 8b79544bb56d 721ba7c5f4ff + 01e29e20ea3f + 32b41ca704e1 + 88714f4125cb + d928b4e8a515 + 88eace5ce682 + 698970a2480b + 29141354a762 + b33fd5ad4c0c + cd345198cf12 + 28be96b80dc1 + 0bab31f71a21 + 40553f55397e e3e6738c56ce 790cdfecd168 469c700e9ed8 @@ -516,21 +612,15 @@ === checking 39bab1cb1cbe === === checking 55bf3fdb634f === === checking 3e1560705803 === - === checking 17b6e6bac221 === - === checking 5ce588c2b7c5 === - === checking f2bdd828a3aa === - === checking a457569c5306 === - === checking ad46a4a0fc10 === - === checking 4f5078f7da8a === - === checking 01e29e20ea3f === - === checking 32b41ca704e1 === - === checking 29141354a762 === === checking 9729470d9329 === === checking 884936b34999 === - === checking 0484d39906c8 === - === checking 5eec91b12a58 === - === checking c84da74cf586 === - === checking 3871506da61e === + === checking b115c694654e === + === checking 8ecb28746ec4 === + === checking de05b9c29ec7 === + === checking d917f77a6439 === + === checking c3c7fa726f88 === + === checking 97d19fc5236f === + === checking 4f5078f7da8a === === checking 2bd677d0f13a === === checking 3bdb00d5c818 === === checking b9c3aa92fba5 === @@ -539,61 +629,179 @@ === checking 2ea3fbf151b5 === === checking 47c836a1f13e === === checking 722d1b8b8942 === + === checking 17b6e6bac221 === + === checking 5ce588c2b7c5 === + === checking f2bdd828a3aa === + === checking a457569c5306 === + === checking ad46a4a0fc10 === === checking 4b39f229a0ce === === checking d94da36be176 === === checking eed373b0090d === - === checking 88714f4125cb === - === checking d928b4e8a515 === - === checking 88eace5ce682 === - === checking 698970a2480b === - === checking b115c694654e === - === checking 1f4a19f83a29 === - === checking 43fc0b77ff07 === - === checking 31d7b43cc321 === + === checking 2472d042ec95 === === checking 673f5499c8c2 === === checking 900dd066a072 === === checking 97ac964e34b7 === === checking 0d153e3ad632 === === checking c37e7cd9f2bd === === checking 9a67238ad1c4 === - === checking 8ecb28746ec4 === - === checking bf6593f7e073 === - === checking 0bab31f71a21 === - === checking 1da228afcf06 === - === checking bfcfd9a61e84 === - === checking d6c9e2d27f14 === - === checking de05b9c29ec7 === - === checking 40553f55397e === - === checking 4f3b41956174 === - === checking 37ad3ab0cddf === - === checking c7d3029bf731 === - === checking 76151e8066e1 === - === checking c7c1497fc270 === - === checking e7135b665740 === - === checking b33fd5ad4c0c === - === checking cd345198cf12 === - === checking 28be96b80dc1 === - === checking c713eae2d31f === - === checking 82238c0bc950 === - === checking dbde319d43a3 === - === checking 8b79544bb56d === - === checking d917f77a6439 === - === checking c3c7fa726f88 === - === checking 97d19fc5236f === - === checking 2472d042ec95 === === checking d99e0f7dad5b === === checking e4cfd6264623 === === checking fac9e582edd1 === === checking 89a0fe204177 === === checking b3cf98c3d587 === === checking 041e1188f5f1 === + === checking 0484d39906c8 === + === checking 5eec91b12a58 === + === checking c84da74cf586 === + === checking 3871506da61e === + === checking bf6593f7e073 === + === checking 1da228afcf06 === + === checking 4f3b41956174 === + === checking bfcfd9a61e84 === + === checking d6c9e2d27f14 === + === checking 37ad3ab0cddf === + === checking c7d3029bf731 === + === checking 1f4a19f83a29 === + === checking 43fc0b77ff07 === + === checking 31d7b43cc321 === + === checking c713eae2d31f === + === checking 76151e8066e1 === + === checking c7c1497fc270 === + === checking e7135b665740 === + === checking 82238c0bc950 === + === checking dbde319d43a3 === + === checking 8b79544bb56d === === checking 721ba7c5f4ff === + === checking 01e29e20ea3f === + === checking 32b41ca704e1 === + === checking 88714f4125cb === + === checking d928b4e8a515 === + === checking 88eace5ce682 === + === checking 698970a2480b === + === checking 29141354a762 === + === checking b33fd5ad4c0c === + === checking cd345198cf12 === + === checking 28be96b80dc1 === + === checking 0bab31f71a21 === + === checking 40553f55397e === === checking e3e6738c56ce === === checking 790cdfecd168 === === checking 469c700e9ed8 === === checking 8ae32c3ed670 === === checking 84d6ec6a8e21 === === checking 01f771406cab === + $ hg showsort --rev 'Cfinal' --limit 72 + c3c7fa726f88 + 97d19fc5236f + 4f5078f7da8a + 2bd677d0f13a + 3bdb00d5c818 + b9c3aa92fba5 + f3441cd3e664 + 0c3f2ba59eb7 + 2ea3fbf151b5 + 47c836a1f13e + 722d1b8b8942 + 17b6e6bac221 + 5ce588c2b7c5 + f2bdd828a3aa + a457569c5306 + ad46a4a0fc10 + 4b39f229a0ce + d94da36be176 + eed373b0090d + 2472d042ec95 + 673f5499c8c2 + 900dd066a072 + 97ac964e34b7 + 0d153e3ad632 + c37e7cd9f2bd + 9a67238ad1c4 + d99e0f7dad5b + e4cfd6264623 + fac9e582edd1 + 89a0fe204177 + b3cf98c3d587 + 041e1188f5f1 + 0484d39906c8 + 5eec91b12a58 + c84da74cf586 + 3871506da61e + bf6593f7e073 + 1da228afcf06 + 4f3b41956174 + bfcfd9a61e84 + d6c9e2d27f14 + 37ad3ab0cddf + c7d3029bf731 + 1f4a19f83a29 + 43fc0b77ff07 + 31d7b43cc321 + c713eae2d31f + 76151e8066e1 + c7c1497fc270 + e7135b665740 + 82238c0bc950 + dbde319d43a3 + 8b79544bb56d + 721ba7c5f4ff + 01e29e20ea3f + 32b41ca704e1 + 88714f4125cb + d928b4e8a515 + 88eace5ce682 + 698970a2480b + 29141354a762 + b33fd5ad4c0c + cd345198cf12 + 28be96b80dc1 + 0bab31f71a21 + 40553f55397e + e3e6738c56ce + 790cdfecd168 + 469c700e9ed8 + 8ae32c3ed670 + 84d6ec6a8e21 + 01f771406cab + $ hg showsort --rev 'Cfinal' --limit 33 + bfcfd9a61e84 + d6c9e2d27f14 + 37ad3ab0cddf + c7d3029bf731 + 1f4a19f83a29 + 43fc0b77ff07 + 31d7b43cc321 + c713eae2d31f + 76151e8066e1 + c7c1497fc270 + e7135b665740 + 82238c0bc950 + dbde319d43a3 + 8b79544bb56d + 721ba7c5f4ff + 01e29e20ea3f + 32b41ca704e1 + 88714f4125cb + d928b4e8a515 + 88eace5ce682 + 698970a2480b + 29141354a762 + b33fd5ad4c0c + cd345198cf12 + 28be96b80dc1 + 0bab31f71a21 + 40553f55397e + e3e6738c56ce + 790cdfecd168 + 469c700e9ed8 + 8ae32c3ed670 + 84d6ec6a8e21 + 01f771406cab + $ hg showsort --rev 'Cfinal' --limit 4 + 469c700e9ed8 + 8ae32c3ed670 + 84d6ec6a8e21 + 01f771406cab Test stability of this mess --------------------------- @@ -619,8 +827,8 @@ $ hg showsort --rev 'all()' > ../crisscross.random.order $ python "$RUNTESTDIR/md5sum.py" ../crisscross.*.order - d9aab0d1907d5cf64d205a8b9036e959 ../crisscross.random.order - d9aab0d1907d5cf64d205a8b9036e959 ../crisscross.source.order + 56271e05099a227fc7c0d6a434c24f0e ../crisscross.random.order + 56271e05099a227fc7c0d6a434c24f0e ../crisscross.source.order $ diff -u ../crisscross.*.order $ hg showsort --rev 'all()' 1ea73414a91b @@ -640,21 +848,15 @@ 39bab1cb1cbe 55bf3fdb634f 3e1560705803 - 17b6e6bac221 - 5ce588c2b7c5 - f2bdd828a3aa - a457569c5306 - ad46a4a0fc10 - 4f5078f7da8a - 01e29e20ea3f - 32b41ca704e1 - 29141354a762 9729470d9329 884936b34999 - 0484d39906c8 - 5eec91b12a58 - c84da74cf586 - 3871506da61e + b115c694654e + 8ecb28746ec4 + de05b9c29ec7 + d917f77a6439 + c3c7fa726f88 + 97d19fc5236f + 4f5078f7da8a 2bd677d0f13a 3bdb00d5c818 b9c3aa92fba5 @@ -663,55 +865,61 @@ 2ea3fbf151b5 47c836a1f13e 722d1b8b8942 + 17b6e6bac221 + 5ce588c2b7c5 + f2bdd828a3aa + a457569c5306 + ad46a4a0fc10 4b39f229a0ce d94da36be176 eed373b0090d - 88714f4125cb - d928b4e8a515 - 88eace5ce682 - 698970a2480b - b115c694654e - 1f4a19f83a29 - 43fc0b77ff07 - 31d7b43cc321 + 2472d042ec95 673f5499c8c2 900dd066a072 97ac964e34b7 0d153e3ad632 c37e7cd9f2bd 9a67238ad1c4 - 8ecb28746ec4 - bf6593f7e073 - 0bab31f71a21 - 1da228afcf06 - bfcfd9a61e84 - d6c9e2d27f14 - de05b9c29ec7 - 40553f55397e - 4f3b41956174 - 37ad3ab0cddf - c7d3029bf731 - 76151e8066e1 - c7c1497fc270 - e7135b665740 - b33fd5ad4c0c - cd345198cf12 - 28be96b80dc1 - c713eae2d31f - 82238c0bc950 - dbde319d43a3 - 8b79544bb56d - d917f77a6439 - c3c7fa726f88 - 97d19fc5236f - 2472d042ec95 d99e0f7dad5b e4cfd6264623 fac9e582edd1 89a0fe204177 b3cf98c3d587 041e1188f5f1 + 0484d39906c8 + 5eec91b12a58 + c84da74cf586 + 3871506da61e + bf6593f7e073 + 1da228afcf06 + 4f3b41956174 + bfcfd9a61e84 + d6c9e2d27f14 + 37ad3ab0cddf + c7d3029bf731 + 1f4a19f83a29 + 43fc0b77ff07 + 31d7b43cc321 + c713eae2d31f + 76151e8066e1 + c7c1497fc270 + e7135b665740 + 82238c0bc950 + dbde319d43a3 + 8b79544bb56d 721ba7c5f4ff + 01e29e20ea3f + 32b41ca704e1 + 88714f4125cb + d928b4e8a515 + 88eace5ce682 + 698970a2480b + 29141354a762 + b33fd5ad4c0c + cd345198cf12 + 28be96b80dc1 + 0bab31f71a21 + 40553f55397e e3e6738c56ce 790cdfecd168 469c700e9ed8 diff -r 875de4816c5b -r bd99cb54712b tests/test-stablesort.t --- a/tests/test-stablesort.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-stablesort.t Mon Dec 11 18:30:15 2017 +0100 @@ -9,7 +9,8 @@ > [ui] > logtemplate = "{rev} {node|short} {desc} {tags}\n" > [alias] - > showsort = debugstablesort --template="{node|short}\n" + > showsort = debugstablesort --template="{node|short}\n" --method basic-mergepoint + > showsorthead = debugstablesort --template="{node|short}\n" --method headcached > EOF @@ -90,22 +91,111 @@ |/ o 0 1ea73414a91b r0 + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + fa942426a6fd 2 + 2b6d669947cd 4 + 4c748ffd1a46 3 + f0f3ef9a6cd5 4 + 2702dd0c91e7 5 + e7d9710d9fc6 5 + d62d843c9a01 6 + dcbb326fdec2 7 + ff43616e5d0f 7 + bab5d5bf48bd 5 + e46a4836065c 6 + b4594d867745 6 + 43227190fef8 5 + 1d8d22637c2d 8 $ hg showsort --rev 'all()' --traceback 1ea73414a91b 66f7d451a68b fa942426a6fd 2b6d669947cd 43227190fef8 + 4c748ffd1a46 + f0f3ef9a6cd5 + 1d8d22637c2d + 2702dd0c91e7 bab5d5bf48bd b4594d867745 - e46a4836065c e7d9710d9fc6 d62d843c9a01 dcbb326fdec2 + e46a4836065c ff43616e5d0f + $ hg showsorthead --rev 1d8d22637c2d + 1ea73414a91b + 66f7d451a68b + fa942426a6fd + 2b6d669947cd + 43227190fef8 + 4c748ffd1a46 + f0f3ef9a6cd5 + 1d8d22637c2d + $ hg showsorthead --rev 1d8d22637c2d --l 4 + 43227190fef8 4c748ffd1a46 f0f3ef9a6cd5 1d8d22637c2d + $ hg showsorthead --rev b4594d867745 + 1ea73414a91b + 66f7d451a68b + fa942426a6fd + 2b6d669947cd + bab5d5bf48bd + b4594d867745 + $ hg showsorthead --rev b4594d867745 --limit 3 + 2b6d669947cd + bab5d5bf48bd + b4594d867745 + $ hg showsorthead --rev e46a4836065c + 1ea73414a91b + 66f7d451a68b + fa942426a6fd + 2b6d669947cd + bab5d5bf48bd + e46a4836065c + $ hg showsorthead --rev e46a4836065c --limit 2 + bab5d5bf48bd + e46a4836065c + $ hg showsorthead --rev ff43616e5d0f + 1ea73414a91b + 66f7d451a68b + fa942426a6fd + 2b6d669947cd + e7d9710d9fc6 + d62d843c9a01 + ff43616e5d0f + $ hg showsorthead --rev ff43616e5d0f --limit 6 + 66f7d451a68b + fa942426a6fd + 2b6d669947cd + e7d9710d9fc6 + d62d843c9a01 + ff43616e5d0f + $ hg showsorthead --rev dcbb326fdec2 + 1ea73414a91b + 66f7d451a68b + fa942426a6fd + 2b6d669947cd + e7d9710d9fc6 + d62d843c9a01 + dcbb326fdec2 + $ hg showsorthead --rev dcbb326fdec2 --limit 4 + 2b6d669947cd + e7d9710d9fc6 + d62d843c9a01 + dcbb326fdec2 + $ hg showsorthead --rev 2702dd0c91e7 + 1ea73414a91b + fa942426a6fd + 4c748ffd1a46 + f0f3ef9a6cd5 + 2702dd0c91e7 + $ hg showsorthead --rev 2702dd0c91e7 --limit 2 + f0f3ef9a6cd5 2702dd0c91e7 Verify the topological order @@ -121,17 +211,17 @@ === checking fa942426a6fd === === checking 2b6d669947cd === === checking 43227190fef8 === - === checking bab5d5bf48bd === - === checking b4594d867745 === - === checking e46a4836065c === - === checking e7d9710d9fc6 === - === checking d62d843c9a01 === - === checking dcbb326fdec2 === - === checking ff43616e5d0f === === checking 4c748ffd1a46 === === checking f0f3ef9a6cd5 === === checking 1d8d22637c2d === === checking 2702dd0c91e7 === + === checking bab5d5bf48bd === + === checking b4594d867745 === + === checking e7d9710d9fc6 === + === checking d62d843c9a01 === + === checking dcbb326fdec2 === + === checking e46a4836065c === + === checking ff43616e5d0f === Check stability =============== @@ -204,6 +294,23 @@ |/ o 0 1ea73414a91b r0 + $ hg -R repo_B debugdepth -r 'all()' + 1ea73414a91b 1 + fa942426a6fd 2 + 4c748ffd1a46 3 + f0f3ef9a6cd5 4 + 66f7d451a68b 2 + 2b6d669947cd 4 + bab5d5bf48bd 5 + b4594d867745 6 + 43227190fef8 5 + 2702dd0c91e7 5 + e7d9710d9fc6 5 + d62d843c9a01 6 + dcbb326fdec2 7 + ff43616e5d0f 7 + e46a4836065c 6 + 1d8d22637c2d 8 $ hg -R repo_B log -G > B.log $ hg clone repo_A repo_C --rev 10 @@ -363,10 +470,10 @@ D $ python "$RUNTESTDIR/md5sum.py" *.all.order - 0c6b2e6f15249c0359b0f93e28c5bd1c A.all.order - 0c6b2e6f15249c0359b0f93e28c5bd1c B.all.order - 0c6b2e6f15249c0359b0f93e28c5bd1c C.all.order - 0c6b2e6f15249c0359b0f93e28c5bd1c D.all.order + 4f54f623da142833149055fb83022a7e A.all.order + 4f54f623da142833149055fb83022a7e B.all.order + 4f54f623da142833149055fb83022a7e C.all.order + 4f54f623da142833149055fb83022a7e D.all.order one specific head @@ -384,6 +491,8 @@ $ for x in $repos; do > hg -R repo_$x showsort --rev '1d8d22637c2d' > ${x}.1d8d22637c2d.order; + > hg -R repo_$x showsorthead --rev '1d8d22637c2d' > ${x}.1d8d22637c2d.orderhead; + > hg -R repo_$x showsorthead --rev '1d8d22637c2d' --limit 4 > ${x}.1d8d22637c2d.orderhead-4; > done $ python "$RUNTESTDIR/md5sum.py" *.1d8d22637c2d.order @@ -391,11 +500,23 @@ 77dc20a6f86db9103df8edaae9ad2754 B.1d8d22637c2d.order 77dc20a6f86db9103df8edaae9ad2754 C.1d8d22637c2d.order 77dc20a6f86db9103df8edaae9ad2754 D.1d8d22637c2d.order + $ python "$RUNTESTDIR/md5sum.py" *.1d8d22637c2d.orderhead + 77dc20a6f86db9103df8edaae9ad2754 A.1d8d22637c2d.orderhead + 77dc20a6f86db9103df8edaae9ad2754 B.1d8d22637c2d.orderhead + 77dc20a6f86db9103df8edaae9ad2754 C.1d8d22637c2d.orderhead + 77dc20a6f86db9103df8edaae9ad2754 D.1d8d22637c2d.orderhead + $ python "$RUNTESTDIR/md5sum.py" *.1d8d22637c2d.orderhead-4 + ea12ffc0007e1b4b911d09dd478881f3 A.1d8d22637c2d.orderhead-4 + ea12ffc0007e1b4b911d09dd478881f3 B.1d8d22637c2d.orderhead-4 + ea12ffc0007e1b4b911d09dd478881f3 C.1d8d22637c2d.orderhead-4 + ea12ffc0007e1b4b911d09dd478881f3 D.1d8d22637c2d.orderhead-4 changeset that are not heads $ for x in $repos; do > hg -R repo_$x showsort --rev 'e7d9710d9fc6+43227190fef8' > ${x}.non-heads.order; + > hg -R repo_$x showsorthead --rev 'e7d9710d9fc6+43227190fef8' > ${x}.non-heads.orderhead; + > hg -R repo_$x showsorthead --rev 'e7d9710d9fc6+43227190fef8' --limit 6 > ${x}.non-heads.orderhead-6; > done $ python "$RUNTESTDIR/md5sum.py" *.non-heads.order @@ -403,6 +524,11 @@ 94e0ea8cdade135dabde4ec5e9954329 B.non-heads.order 94e0ea8cdade135dabde4ec5e9954329 C.non-heads.order 94e0ea8cdade135dabde4ec5e9954329 D.non-heads.order + $ python "$RUNTESTDIR/md5sum.py" *.non-heads.orderhead + 1e5ce05b507a058c5dac3d7de9ae8feb A.non-heads.orderhead + 1e5ce05b507a058c5dac3d7de9ae8feb B.non-heads.orderhead + 1e5ce05b507a058c5dac3d7de9ae8feb C.non-heads.orderhead + 1e5ce05b507a058c5dac3d7de9ae8feb D.non-heads.orderhead Check with different subset @@ -464,6 +590,8 @@ $ for x in E F G; do > hg -R repo_$x showsort --rev 'e7d9710d9fc6+43227190fef8' > ${x}.non-heads.order; + > hg -R repo_$x showsort --rev 'e7d9710d9fc6' > ${x}.non-head-A.orderhead; + > hg -R repo_$x showsort --rev '43227190fef8' > ${x}.non-head-B.orderhead; > done $ python "$RUNTESTDIR/md5sum.py" *.non-heads.order @@ -474,6 +602,14 @@ 94e0ea8cdade135dabde4ec5e9954329 E.non-heads.order 94e0ea8cdade135dabde4ec5e9954329 F.non-heads.order 94e0ea8cdade135dabde4ec5e9954329 G.non-heads.order + $ python "$RUNTESTDIR/md5sum.py" *.non-head-A.orderhead + 1e5ce05b507a058c5dac3d7de9ae8feb E.non-head-A.orderhead + 1e5ce05b507a058c5dac3d7de9ae8feb F.non-head-A.orderhead + 1e5ce05b507a058c5dac3d7de9ae8feb G.non-head-A.orderhead + $ python "$RUNTESTDIR/md5sum.py" *.non-head-B.orderhead + 4b07febabfee9528aedcea156a7d7071 E.non-head-B.orderhead + 4b07febabfee9528aedcea156a7d7071 F.non-head-B.orderhead + 4b07febabfee9528aedcea156a7d7071 G.non-head-B.orderhead Multiple recursions =================== @@ -534,6 +670,28 @@ |/ o 0 1ea73414a91b r0 base + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + e7bd5218ca15 2 + 3a367db1fabc 3 + a2f58e9c1e56 4 + 5f18015f9110 8 + abf57d94268b 5 + 529dfc5bb875 6 + 6ee532b68cfa 3 + 001194dd78d5 9 + a66b68853635 10 + 013b27f11536 11 + 4bbfc6078919 12 + 9fff0871d230 9 + 4dbf739dd63f 10 + d64d500024d1 11 + 0496f0a6a143 16 + 1c645e73dbc6 17 + 160a7a0adbf4 18 $ hg showsort --rev 'all()' 1ea73414a91b 66f7d451a68b @@ -542,17 +700,68 @@ abf57d94268b 529dfc5bb875 e7bd5218ca15 + 6ee532b68cfa + 001194dd78d5 + 3a367db1fabc + a2f58e9c1e56 + 5f18015f9110 + 9fff0871d230 + 4dbf739dd63f + d64d500024d1 + 0496f0a6a143 + 1c645e73dbc6 + 160a7a0adbf4 + a66b68853635 + 013b27f11536 + 4bbfc6078919 + $ hg showsorthead --rev '160a7a0adbf4' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + abf57d94268b + 529dfc5bb875 + e7bd5218ca15 + 6ee532b68cfa + 001194dd78d5 3a367db1fabc a2f58e9c1e56 5f18015f9110 9fff0871d230 4dbf739dd63f d64d500024d1 - 6ee532b68cfa - 001194dd78d5 + 0496f0a6a143 + 1c645e73dbc6 + 160a7a0adbf4 + $ hg showsorthead --rev '160a7a0adbf4' --limit 7 + 5f18015f9110 + 9fff0871d230 + 4dbf739dd63f + d64d500024d1 0496f0a6a143 1c645e73dbc6 160a7a0adbf4 + $ hg showsorthead --rev '4bbfc6078919' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + abf57d94268b + 529dfc5bb875 + e7bd5218ca15 + 6ee532b68cfa + 001194dd78d5 + a66b68853635 + 013b27f11536 + 4bbfc6078919 + $ hg showsorthead --rev '4bbfc6078919' --limit 10 + 01241442b3c2 + 2dc09a01254d + abf57d94268b + 529dfc5bb875 + e7bd5218ca15 + 6ee532b68cfa + 001194dd78d5 a66b68853635 013b27f11536 4bbfc6078919 @@ -564,14 +773,14 @@ === checking abf57d94268b === === checking 529dfc5bb875 === === checking e7bd5218ca15 === + === checking 6ee532b68cfa === + === checking 001194dd78d5 === === checking 3a367db1fabc === === checking a2f58e9c1e56 === === checking 5f18015f9110 === === checking 9fff0871d230 === === checking 4dbf739dd63f === === checking d64d500024d1 === - === checking 6ee532b68cfa === - === checking 001194dd78d5 === === checking 0496f0a6a143 === === checking 1c645e73dbc6 === === checking 160a7a0adbf4 === @@ -579,6 +788,8 @@ === checking 013b27f11536 === === checking 4bbfc6078919 === $ hg showsort --rev 'all()' > ../multiple.source.order + $ hg showsorthead --rev '160a7a0adbf4' > ../160a7a0adbf4.source.orderhead + $ hg showsorthead --rev '4bbfc6078919' > ../4bbfc6078919.source.orderhead $ hg log -r tip 20 160a7a0adbf4 r20 tip $ cd .. @@ -597,9 +808,17 @@ > done; $ hg pull --quiet $ hg showsort --rev 'all()' > ../multiple.random.order + $ hg showsorthead --rev '160a7a0adbf4' > ../160a7a0adbf4.random.orderhead + $ hg showsorthead --rev '4bbfc6078919' > ../4bbfc6078919.random.orderhead $ python "$RUNTESTDIR/md5sum.py" ../multiple.*.order - 6ff802a0a5f0a3ddd82b25f860238fbd ../multiple.random.order - 6ff802a0a5f0a3ddd82b25f860238fbd ../multiple.source.order + a6547220a9f004c975e365d9561639dd ../multiple.random.order + a6547220a9f004c975e365d9561639dd ../multiple.source.order + $ python "$RUNTESTDIR/md5sum.py" ../160a7a0adbf4.*.orderhead + 48d8911f53869b32e29da26c56e95119 ../160a7a0adbf4.random.orderhead + 48d8911f53869b32e29da26c56e95119 ../160a7a0adbf4.source.orderhead + $ python "$RUNTESTDIR/md5sum.py" ../4bbfc6078919.*.orderhead + 3732305a333d59ec50b91db0f5ab696e ../4bbfc6078919.random.orderhead + 3732305a333d59ec50b91db0f5ab696e ../4bbfc6078919.source.orderhead $ hg showsort --rev 'all()' 1ea73414a91b 66f7d451a68b @@ -608,20 +827,52 @@ abf57d94268b 529dfc5bb875 e7bd5218ca15 + 6ee532b68cfa + 001194dd78d5 3a367db1fabc a2f58e9c1e56 5f18015f9110 9fff0871d230 4dbf739dd63f d64d500024d1 - 6ee532b68cfa - 001194dd78d5 0496f0a6a143 1c645e73dbc6 160a7a0adbf4 a66b68853635 013b27f11536 4bbfc6078919 + $ hg showsorthead --rev '160a7a0adbf4' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + abf57d94268b + 529dfc5bb875 + e7bd5218ca15 + 6ee532b68cfa + 001194dd78d5 + 3a367db1fabc + a2f58e9c1e56 + 5f18015f9110 + 9fff0871d230 + 4dbf739dd63f + d64d500024d1 + 0496f0a6a143 + 1c645e73dbc6 + 160a7a0adbf4 + $ hg showsorthead --rev '4bbfc6078919' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + abf57d94268b + 529dfc5bb875 + e7bd5218ca15 + 6ee532b68cfa + 001194dd78d5 + a66b68853635 + 013b27f11536 + 4bbfc6078919 $ cd .. @@ -662,9 +913,186 @@ |/ o 0 d20a80d4def3 base + $ hg debugdepth -r 'all()' + d20a80d4def3 1 + 47da0f2c25e2 2 + 0dedbcd995b6 3 + ed776db7ed63 4 + 7f2454f6b04f 5 $ hg showsort --rev '.' d20a80d4def3 47da0f2c25e2 0dedbcd995b6 ed776db7ed63 7f2454f6b04f + $ hg showsorthead --rev '.' + d20a80d4def3 + 47da0f2c25e2 + 0dedbcd995b6 + ed776db7ed63 + 7f2454f6b04f + + $ cd .. + +Merge two branches with their own independant internal merge. +------------------------------------------------------------- + + $ hg init subbranch + $ cd subbranch + $ hg debugbuilddag ' + > .:base + > +3:leftBranch + > +2:leftA + > /leftA:leftMerge + > +4:rightA + > /rightA:rightMerge + > +3/leftMerge + > ' + $ hg log -G + o 22 56526aefbff4 r22 tip + |\ + | o 21 d4422659bc40 r21 + | | + | o 20 6a97ef856f90 r20 + | | + | o 19 5648bbf0e38b r19 + | | + | o 18 4442c125b80d r18 rightMerge + | |\ + | | o 17 65e683dd6db4 r17 rightB + | | | + | | o 16 5188cf52b7b7 r16 + | | | + | o | 15 191bac7bf37c r15 rightA + | | | + | o | 14 5cb8e6902ff3 r14 + | | | + | o | 13 448a7ac3ab1f r13 + | | | + | o | 12 ee222cc71ce6 r12 + | |/ + | o 11 e5c0d969abc4 r11 rightBranch + | | + | o 10 7cc044fdf4a7 r10 + | | + o | 9 9f6c364a3574 r9 leftMerge + |\ \ + | o | 8 588f0bc87ecd r8 leftB + | | | + | o | 7 e2317cea05f7 r7 + | | | + | o | 6 c2c595bcd4c6 r6 + | | | + o | | 5 c8d03c1b5e94 r5 leftA + | | | + o | | 4 bebd167eb94d r4 + |/ / + o | 3 2dc09a01254d r3 leftBranch + | | + o | 2 01241442b3c2 r2 + | | + o | 1 66f7d451a68b r1 + |/ + o 0 1ea73414a91b r0 base + + $ hg debugdepth -r 'all()' + 1ea73414a91b 1 + 66f7d451a68b 2 + 01241442b3c2 3 + 2dc09a01254d 4 + bebd167eb94d 5 + c8d03c1b5e94 6 + c2c595bcd4c6 5 + e2317cea05f7 6 + 588f0bc87ecd 7 + 9f6c364a3574 10 + 7cc044fdf4a7 2 + e5c0d969abc4 3 + ee222cc71ce6 4 + 448a7ac3ab1f 5 + 5cb8e6902ff3 6 + 191bac7bf37c 7 + 5188cf52b7b7 4 + 65e683dd6db4 5 + 4442c125b80d 10 + 5648bbf0e38b 11 + 6a97ef856f90 12 + d4422659bc40 13 + 56526aefbff4 23 + $ hg showsort --rev 'tip' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + c2c595bcd4c6 + e2317cea05f7 + 588f0bc87ecd + bebd167eb94d + c8d03c1b5e94 + 9f6c364a3574 + 7cc044fdf4a7 + e5c0d969abc4 + ee222cc71ce6 + 448a7ac3ab1f + 5cb8e6902ff3 + 191bac7bf37c + 5188cf52b7b7 + 65e683dd6db4 + 4442c125b80d + 5648bbf0e38b + 6a97ef856f90 + d4422659bc40 + 56526aefbff4 + $ hg showsorthead --rev 'tip' + 1ea73414a91b + 66f7d451a68b + 01241442b3c2 + 2dc09a01254d + c2c595bcd4c6 + e2317cea05f7 + 588f0bc87ecd + bebd167eb94d + c8d03c1b5e94 + 9f6c364a3574 + 7cc044fdf4a7 + e5c0d969abc4 + ee222cc71ce6 + 448a7ac3ab1f + 5cb8e6902ff3 + 191bac7bf37c + 5188cf52b7b7 + 65e683dd6db4 + 4442c125b80d + 5648bbf0e38b + 6a97ef856f90 + d4422659bc40 + 56526aefbff4 + $ hg showsorthead --rev 'tip' --limit 12 + e5c0d969abc4 + ee222cc71ce6 + 448a7ac3ab1f + 5cb8e6902ff3 + 191bac7bf37c + 5188cf52b7b7 + 65e683dd6db4 + 4442c125b80d + 5648bbf0e38b + 6a97ef856f90 + d4422659bc40 + 56526aefbff4 + $ hg showsorthead --rev 'tip' --limit 7 + 5188cf52b7b7 + 65e683dd6db4 + 4442c125b80d + 5648bbf0e38b + 6a97ef856f90 + d4422659bc40 + 56526aefbff4 + $ hg showsorthead --rev 'tip' --limit 3 + 6a97ef856f90 + d4422659bc40 + 56526aefbff4 + $ cd .. diff -r 875de4816c5b -r bd99cb54712b tests/test-topic-flow-reject-untopiced.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-topic-flow-reject-untopiced.t Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,174 @@ +Testing the config option for rejecting draft changeset without topic +The config option is "experimental.topic-mode.server" + + $ . "$TESTDIR/testlib/topic_setup.sh" + +Creating a server repo + + $ hg init server + $ cd server + $ cat <>.hg/hgrc + > [phases] + > publish=False + > [experimental] + > topic-mode.server = enforce + > EOF + + $ hg topic server + marked working directory as topic: server + $ for ch in a b c; do echo foo > $ch; hg ci -Aqm "Added "$ch; done + $ hg ph -p 0 + + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a + + $ cd .. + +Creating a client repo + + $ hg clone server client + updating to branch default + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ cd client + $ hg up server + switching to topic server + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a + + $ hg topic + * server (2 changesets) + +Create a changeset without topic + + $ hg topic --clear + $ echo foo > d + $ hg ci -Aqm "added d" + + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 3:4e8b0e0237c6 + | added d + o 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a + +Push a draft changeset without topic + + $ hg push ../server --new-branch + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + + $ hg push ../server -f + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + +Grow the stack with more changesets having topic + + $ hg topic client + marked working directory as topic: client + $ for ch in e f g; do echo foo > $ch; hg ci -Aqm "Added "$ch; done; + + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 6:42c4ac86452a + | Added g client + o 5:3dc456efb491 + | Added f client + o 4:18a516babc60 + | Added e client + o 3:4e8b0e0237c6 + | added d + o 2:a7b96f87a214 + | Added c server + o 1:d6a8197e192a + | Added b server + o 0:49a3f206c9ae + Added a + +Pushing multiple changeset with some having topics and some not + + $ hg push ../server --new-branch + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 4 changes to 4 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + +Testing case when both experimental.topic-mode.server and +experimental.topic.publish-bare-branch are set + + $ cd ../server + $ echo 'topic.publish-bare-branch=True' >> .hg/hgrc + $ cd ../client + $ hg push ../server --new-branch + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 4 changes to 4 files + transaction abort! + rollback completed + abort: rejecting draft changesets: 4e8b0e0237 + [255] + +Turning the changeset public and testing push + + $ hg phase -r 3 -p + $ hg log -G -T "{rev}:{node|short}\n{desc} {topics}" + @ 6:42c4ac86452a + | Added g client + o 5:3dc456efb491 + | Added f client + o 4:18a516babc60 + | Added e client + o 3:4e8b0e0237c6 + | added d + o 2:a7b96f87a214 + | Added c + o 1:d6a8197e192a + | Added b + o 0:49a3f206c9ae + Added a + + $ hg push ../server + pushing to ../server + searching for changes + adding changesets + adding manifests + adding file changes + added 4 changesets with 4 changes to 4 files + active topic 'server' is now empty diff -r 875de4816c5b -r bd99cb54712b tests/test-topic-stack-complex.t --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/test-topic-stack-complex.t Mon Dec 11 18:30:15 2017 +0100 @@ -0,0 +1,225 @@ +Testing `hg stack` on complex cases when we have multiple successors because of +divergence, split etc. + $ . "$TESTDIR/testlib/topic_setup.sh" + +Setup + + $ cat << EOF >> $HGRCPATH + > [experimental] + > evolution = all + > [ui] + > interactive = True + > [defaults] + > split = -d "0 "0 + > [extensions] + > EOF + $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH + + $ hg init test + $ cd test + $ echo foo > foo + $ hg add foo + $ hg ci -m "Added foo" + $ hg phase -r . --public + $ hg topic foo + marked working directory as topic: foo + $ echo a > a + $ echo b > b + $ hg ci -Aqm "Added a and b" + $ echo c > c + $ echo d > d + $ hg ci -Aqm "Added c and d" + $ echo e > e + $ echo f > f + $ hg ci -Aqm "Added e and f" + $ hg log -G + @ changeset: 3:f1d3649d6a8b + | tag: tip + | topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: Added e and f + | + o changeset: 2:8e8251e8193b + | topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: Added c and d + | + o changeset: 1:002b85930b9c + | topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: Added a and b + | + o changeset: 0:f3603c09ac10 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: Added foo + + +Testing in case of split within the topic + + $ 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) + $ hg prev + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + [2] Added c and d + + $ echo 0 > num + $ cat > editor.sh << '__EOF__' + > NUM=$(cat num) + > NUM=`expr "$NUM" + 1` + > echo "$NUM" > num + > echo "split$NUM" > "$1" + > __EOF__ + $ export HGEDITOR="\"sh\" \"editor.sh\"" + + $ hg split << EOF + > y + > y + > n + > y + > EOF + 0 files updated, 0 files merged, 2 files removed, 0 files unresolved + adding c + adding d + diff --git a/c b/c + new file mode 100644 + examine changes to 'c'? [Ynesfdaq?] y + + @@ -0,0 +1,1 @@ + +c + record change 1/2 to 'c'? [Ynesfdaq?] y + + diff --git a/d b/d + new file mode 100644 + examine changes to 'd'? [Ynesfdaq?] n + + Done splitting? [yN] y + + $ 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) + + $ hg log -G + @ changeset: 5:5ccee6da565e + | tag: tip + | topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: split2 + | + o changeset: 4:f26c1b9addde + | topic: foo + | parent: 1:002b85930b9c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: split1 + | + | o changeset: 3:f1d3649d6a8b + | | topic: foo + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | trouble: unstable + | | summary: Added e and f + | | + | x changeset: 2:8e8251e8193b + |/ topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: Added c and d + | + o changeset: 1:002b85930b9c + | topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: Added a and b + | + o changeset: 0:f3603c09ac10 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: Added foo + + + $ hg prev + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + [4] split1 + $ echo foo > c + $ hg diff + diff -r f26c1b9addde c + --- a/c Thu Jan 01 00:00:00 1970 +0000 + +++ b/c * (glob) + @@ -1,1 +1,1 @@ + -c + +foo + + $ hg amend + 1 new unstable changesets + + $ hg log -G + @ changeset: 7:7d9445714d83 + | tag: tip + | topic: foo + | parent: 1:002b85930b9c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: split1 + | + | o changeset: 5:5ccee6da565e + | | topic: foo + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | trouble: unstable + | | summary: split2 + | | + | x changeset: 4:f26c1b9addde + |/ topic: foo + | parent: 1:002b85930b9c + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: split1 + | + | o changeset: 3:f1d3649d6a8b + | | topic: foo + | | user: test + | | date: Thu Jan 01 00:00:00 1970 +0000 + | | trouble: unstable + | | summary: Added e and f + | | + | x changeset: 2:8e8251e8193b + |/ topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: Added c and d + | + o changeset: 1:002b85930b9c + | topic: foo + | user: test + | date: Thu Jan 01 00:00:00 1970 +0000 + | summary: Added a and b + | + o changeset: 0:f3603c09ac10 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: Added foo + + + $ 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) diff -r 875de4816c5b -r bd99cb54712b tests/test-topic-stack.t diff -r 875de4816c5b -r bd99cb54712b tests/test-touch.t --- a/tests/test-touch.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-touch.t Mon Dec 11 18:30:15 2017 +0100 @@ -125,3 +125,8 @@ 1 changesets pruned $ hg touch 14 --hidden 1 new unstable changesets + $ hg obslog -r 14 --hidden + x [0-9a-f]{12} (.*) move (re) + pruned by test (*) (glob) + rewritten(.*) as [0-9a-f]{12} by test (.*) (re) + diff -r 875de4816c5b -r bd99cb54712b tests/test-tutorial.t --- a/tests/test-tutorial.t Mon Dec 11 09:33:32 2017 +0100 +++ b/tests/test-tutorial.t Mon Dec 11 18:30:15 2017 +0100 @@ -936,6 +936,7 @@ -a --all uncommit all changes when no arguments given -r --rev VALUE revert commit content to REV instead + -n --note VALUE store a note on uncommit -I --include PATTERN [+] include names matching the given patterns -X --exclude PATTERN [+] exclude names matching the given patterns -m --message TEXT use text as commit message @@ -975,6 +976,7 @@ -r --rev VALUE [+] revision to fold --exact only fold specified revisions --from fold revisions linearly to working copy parent + -n --note VALUE store a note on fold -m --message TEXT use text as commit message -l --logfile FILE read commit message from file -d --date DATE record the specified date as commit date diff -r 875de4816c5b -r bd99cb54712b tests/test-wireproto.t