--- 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
-------------------
--- 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"))
--- 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():
--- 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 = {}
--- /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()
--- /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 <contact@octobus.net>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+from __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 <data> 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 <data> 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)
--- 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/'
--- 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))
--- 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):
--- 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 <range>"""
+ 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 `(<head>, <skip>)` contains all revisions stable-sorted from
+ <head>, skipping the <index>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 <range>"""
+ 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 <range>"""
+ 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 `(<head>, <skip>)` contains all revisions stable-sorted from
+ <head>, skipping the <index>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 = []
--- /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 <pierre-yves.david@ens-lyon.org>
+#
+# 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.
+ * <insert-your-idea>
+ """
+ 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,
+}
--- /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)
--- 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)
--- 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()
--- 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))
--- 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',
--- 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
--- 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
--- 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)
--- 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)
--- 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
--- 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
--- /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
--- 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
--- /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
+ > <base+3:right
+ > <left/right:merge
+ > +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
+ > <base+5:right
+ > <left/right:merge
+ > +2:head
+ > '
+ $ hg debugbuilddag '.:base
+ > +3:left
+ > <base+3:right
+ > <left/right:merge
+ > +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"
+ > <m+3:a # 3 nodes base on the "m" tag
+ > <2.:b # 1 node based on -2; tagged "b"
+ > <m+2:d # 2 nodes from "m" tagged "d"
+ > <2.:e # 1 node based on -2, tagged "e"
+ > <m+1:f # 1 node based on "m" tagged "f"
+ > <i/f # merge "i" and "f"
+ > '
+ $ 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] -
+
--- 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] -
--- /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"
+ > <base+2:AbaseB # "B" branch for CC "B"
+ > <AbaseA/AbaseB:AmergeA
+ > <AbaseB/AbaseA:AmergeB
+ > <AmergeA/AmergeB:Afinal
+ > # criss cross #2:multiple closes ones
+ > .:BbaseA
+ > <AmergeB:BbaseB
+ > <BbaseA/BbaseB:BmergeA
+ > <BbaseB/BbaseA:BmergeB
+ > <BmergeA/BmergeB:BmergeC
+ > <BmergeB/BmergeA:BmergeD
+ > <BmergeC/BmergeD:Bfinal
+ > # criss cross #2:many branches
+ > <Bfinal.:CbaseA
+ > <Bfinal+2:CbaseB
+ > <Bfinal.:CbaseC
+ > <Bfinal+5:CbaseD
+ > <Bfinal.:CbaseE
+ > <CbaseA/CbaseB+7:CmergeA
+ > <CbaseA/CbaseC:CmergeB
+ > <CbaseA/CbaseD.:CmergeC
+ > <CbaseA/CbaseE:CmergeD
+ > <CbaseB/CbaseA+2:CmergeE
+ > <CbaseB/CbaseC:CmergeF
+ > <CbaseB/CbaseD.:CmergeG
+ > <CbaseB/CbaseE:CmergeH
+ > <CbaseC/CbaseA.:CmergeI
+ > <CbaseC/CbaseB:CmergeJ
+ > <CbaseC/CbaseD+5:CmergeK
+ > <CbaseC/CbaseE+2:CmergeL
+ > <CbaseD/CbaseA:CmergeM
+ > <CbaseD/CbaseB...:CmergeN
+ > <CbaseD/CbaseC:CmergeO
+ > <CbaseD/CbaseE:CmergeP
+ > <CbaseE/CbaseA:CmergeQ
+ > <CbaseE/CbaseB..:CmergeR
+ > <CbaseE/CbaseC.:CmergeS
+ > <CbaseE/CbaseD:CmergeT
+ > <CmergeA/CmergeG:CmergeWA
+ > <CmergeB/CmergeF:CmergeWB
+ > <CmergeC/CmergeE:CmergeWC
+ > <CmergeD/CmergeH:CmergeWD
+ > <CmergeT/CmergeI:CmergeWE
+ > <CmergeS/CmergeJ:CmergeWF
+ > <CmergeR/CmergeK:CmergeWG
+ > <CmergeQ/CmergeL:CmergeWH
+ > <CmergeP/CmergeM:CmergeWI
+ > <CmergeO/CmergeN:CmergeWJ
+ > <CmergeO/CmergeN:CmergeWK
+ > <CmergeWA/CmergeWG:CmergeXA
+ > <CmergeWB/CmergeWH:CmergeXB
+ > <CmergeWC/CmergeWI:CmergeXC
+ > <CmergeWD/CmergeWJ:CmergeXD
+ > <CmergeWE/CmergeWK:CmergeXE
+ > <CmergeWF/CmergeWA:CmergeXF
+ > <CmergeXA/CmergeXF:CmergeYA
+ > <CmergeXB/CmergeXE:CmergeYB
+ > <CmergeXC/CmergeXD:CmergeYC
+ > <CmergeYA/CmergeYB:CmergeZA
+ > <CmergeYC/CmergeYB:CmergeZB
+ > <CmergeZA/CmergeZB:Cfinal
+ > '
+ $ 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
--- /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"
+ > <m+3:a # 3 nodes base on the "m" tag
+ > <2.:b # 1 node based on -2; tagged "b"
+ > <m+2:d # 2 nodes from "m" tagged "d"
+ > <2.:e # 1 node based on -2, tagged "e"
+ > <m+1:f # 1 node based on "m" tagged "f"
+ > <i/f # merge "i" and "f"
+ > '
+ $ 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
+ > <base.:B
+ > +2/A:C
+ > <A+2:D
+ > <B./D:E
+ > +3:F
+ > <C+3/E
+ > +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
+ > <leftBranch.+2:leftB
+ > /leftA:leftMerge
+ > <base+2:rightBranch
+ > +4:rightA
+ > <rightBranch.+1:rightB
+ > /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 ..
--- 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
--- 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
+ > <leftBranch.+2:leftB
+ > /leftA:leftMerge
+ > <base+2:rightBranch
+ > +4:rightA
+ > <rightBranch.+1:rightB
+ > /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 ..
--- /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 <<EOF >>.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
--- /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)
--- 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)
+
--- 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