merge with future 6.2.0
The new 'olog' command is not working with 3.9 so we skill all mentions of it in
the tests. This also apply to the topic extensions.
--- a/.hgtags Wed May 03 13:23:36 2017 +0200
+++ b/.hgtags Thu May 18 23:51:10 2017 +0200
@@ -48,3 +48,4 @@
70694b2621ba9d919bc38303f8901e84caf5da0f 5.6.1
165ad227993de4e7d819cc6c820d5b9f7b38b80d 6.0.0
5ef112a6eb875633a7925cde61b7d2d9e65b3a56 6.0.1
+8510d3fd7c3b312dc731f4c29badc415d504558a 6.1.0
--- a/README Wed May 03 13:23:36 2017 +0200
+++ b/README Thu May 18 23:51:10 2017 +0200
@@ -112,7 +112,24 @@
Changelog
=========
-6.1.0 - in progress
+6.2.0 -- 2017-05-18
+-------------------
+
+ - olog: a new command to inspect the obs-history of a changeset (hg-4.0 + only),
+ - topic: have thg display topic name if possible,
+ - blackbox: log more information about discovery and cache computation,
+ - obscache: more efficient update in the (rare) case of a transaction adding
+ markers without changesets,
+ - obscache: fix more cache invalidation propagation,
+ - obscache: also enable the new cache (from 6.1.0) for 'evolve.server-only',
+ - obshashrange-cache: update incrementally in the (common) case of a
+ transaction not affecting existing range,
+ - obshashrange-cache: keep the cache warm after each transaction,
+ - topic: now requires Mercurial 4.0 or above,
+ - stack: now display if current revision is in bad state (issue5533),
+ - stack: fix json output to be valid json.
+
+6.1.0 -- 2017-05-03
-------------------
- improve message about obsolete working copy parent,
--- a/debian/changelog Wed May 03 13:23:36 2017 +0200
+++ b/debian/changelog Thu May 18 23:51:10 2017 +0200
@@ -1,14 +1,26 @@
-mercurial-evolve (6.0.1-1) UNRELEASED; urgency=medium
+mercurial-evolve (6.2.0-1) unstable; urgency=medium
+
+ * new upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org> Thu, 18 May 2017 22:24:10 +0200
+
+mercurial-evolve (6.1.0-1) unstable; urgency=medium
+
+ * New upstream release
+
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org> Wed, 03 May 2017 13:57:15 +0200
+
+mercurial-evolve (6.0.1-1) unstable; urgency=medium
* New upstream version
- -- Pierre-Yves David <marmoute@nodosa.octopoid.net> Thu, 20 Apr 2017 12:58:35 +0200
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org> Thu, 20 Apr 2017 12:58:35 +0200
mercurial-evolve (6.0.0-1) unstable; urgency=medium
* New Upstream Release
- -- Pierre-Yves David <marmoute@nodosa.octopoid.net> Thu, 20 Apr 2017 12:58:03 +0200
+ -- Pierre-Yves David <pierre-yves.david@ens-lyon.org> Thu, 20 Apr 2017 12:58:03 +0200
mercurial-evolve (5.5.0-1) unstable; urgency=medium
--- a/hgext3rd/evolve/__init__.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/evolve/__init__.py Thu May 18 23:51:10 2017 +0200
@@ -148,6 +148,7 @@
obsexchange,
safeguard,
utility,
+ obshistory
)
__version__ = metadata.__version__
@@ -162,6 +163,15 @@
obsexcmsg = utility.obsexcmsg
+colortable = {'evolve.node': 'yellow',
+ 'evolve.user': 'green',
+ 'evolve.rev': 'blue',
+ 'evolve.short_description': '',
+ 'evolve.date': 'cyan',
+ 'evolve.current_rev': 'bold',
+ 'evolve.verb': '',
+ }
+
_pack = struct.pack
_unpack = struct.unpack
@@ -180,6 +190,7 @@
eh.merge(checkheads.eh)
eh.merge(safeguard.eh)
eh.merge(obscache.eh)
+eh.merge(obshistory.eh)
uisetup = eh.final_uisetup
extsetup = eh.final_extsetup
reposetup = eh.final_reposetup
@@ -269,9 +280,6 @@
ui.setconfig('alias', 'pstatus', 'status --rev .^', 'evolve')
if ui.config('alias', 'pdiff', None) is None:
ui.setconfig('alias', 'pdiff', 'diff --rev .^', 'evolve')
- if ui.config('alias', 'olog', None) is None:
- ui.setconfig('alias', 'olog', "log -r 'precursors(.)' --hidden",
- 'evolve')
if ui.config('alias', 'odiff', None) is None:
ui.setconfig('alias', 'odiff',
"diff --hidden --rev 'limit(precursors(.),1)' --rev .",
@@ -1881,7 +1889,7 @@
raise error.Abort("base of divergent changeset %s not found" % ctx,
hint='this case is not yet handled')
-shorttemplate = '[{rev}] {desc|firstline}\n'
+shorttemplate = "[{label('evolve.rev', rev)}] {desc|firstline}\n"
@eh.command(
'^previous',
@@ -2055,7 +2063,8 @@
result = _solveone(ui, repo, repo[aspchildren[0]], dryrunopt,
False, lambda: None, category='unstable')
if not result:
- ui.status(_('working directory now at %s\n') % repo['.'])
+ ui.status(_('working directory now at %s\n')
+ % ui.label(repo['.'], 'evolve.node'))
return result
return 1
return result
@@ -2261,7 +2270,8 @@
repo._bookmarks[bookactive] = newnode.node()
repo._bookmarks.recordchange(tr)
commands.update(ui, repo, newnode.rev())
- ui.status(_('working directory now at %s\n') % newnode)
+ ui.status(_('working directory now at %s\n')
+ % ui.label(newnode, 'evolve.node'))
if movebookmark:
bookmarksmod.activate(repo, bookactive)
--- a/hgext3rd/evolve/metadata.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/evolve/metadata.py Thu May 18 23:51:10 2017 +0200
@@ -5,7 +5,7 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-__version__ = '6.1.0.dev'
-testedwith = '3.8.4 3.9.2 4.0.2 4.1.1 4.2'
+__version__ = '6.2.0'
+testedwith = '3.8.4 3.9.2 4.0.2 4.1.2 4.2'
minimumhgversion = '3.8'
buglink = 'https://bz.mercurial-scm.org/'
--- a/hgext3rd/evolve/obscache.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/evolve/obscache.py Thu May 18 23:51:10 2017 +0200
@@ -7,25 +7,42 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
+import errno
import hashlib
+import os
import struct
+import time
import weakref
-import errno
from mercurial import (
+ error,
localrepo,
obsolete,
phases,
+ pycompat,
node,
util,
)
+from mercurial.i18n import _
+
from . import (
exthelper,
)
eh = exthelper.exthelper()
+# 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
+
+
try:
obsstorefilecache = localrepo.localrepository.obsstore
except AttributeError:
@@ -76,91 +93,235 @@
except (OSError, IOError) as e:
if e.errno != errno.ENOENT:
raise
- key = hashlib.sha1(keydata).digest()
+ if keydata:
+ key = hashlib.sha1(keydata).digest()
+ else:
+ # reusing an existing "empty" value make it easier to define a
+ # default cachekey for 'no data'.
+ key = node.nullid
return obsstoresize, key
obsstore.__class__ = cachekeyobsstore
return obsstore
-emptykey = (node.nullrev, node.nullid, 0, 0, node.nullid)
-
-def getcachekey(repo):
- """get a cache key covering the changesets and obsmarkers content
-
- IT contains the following data. Combined with 'upgradeneeded' it allows to
- do iterative upgrade for cache depending of theses two data.
+# XXX copied as is from Mercurial 4.2 and added the "offset" parameters
+@util.nogc
+def _readmarkers(data, offset=None):
+ """Read and enumerate markers from raw data"""
+ off = 0
+ diskversion = struct.unpack('>B', data[off:off + 1])[0]
+ if offset is None:
+ off += 1
+ else:
+ assert 1 <= offset
+ off = offset
+ if diskversion not in obsolete.formats:
+ raise error.Abort(_('parsing obsolete marker: unknown version %r')
+ % diskversion)
+ return diskversion, obsolete.formats[diskversion][0](data, off)
- The cache key parts are"
- - tip-rev,
- - tip-node,
- - obsstore-length (nb markers),
- - obsstore-file-size (in bytes),
- - obsstore "cache key"
- """
- assert repo.filtername is None
- cl = repo.changelog
- index, key = repo.obsstore.cachekey()
- tiprev = len(cl) - 1
- return (tiprev,
- cl.node(tiprev),
- len(repo.obsstore),
- index,
- key)
+def markersfrom(obsstore, byteoffset, firstmarker):
+ if not firstmarker:
+ return list(obsstore)
+ elif '_all' in vars(obsstore):
+ # if the data are in memory, just use that
+ return obsstore._all[firstmarker:]
+ else:
+ obsdata = obsstore.svfs.tryread('obsstore')
+ return _readmarkers(obsdata, byteoffset)[1]
-def upgradeneeded(repo, key):
- """return (valid, start-rev, start-obs-idx)
- 'valid': is "False" if older cache value needs invalidation,
+class dualsourcecache(object):
+ """An abstract class for cache that needs both changelog and obsstore
- 'start-rev': first revision not in the cache. None if cache is up to date,
-
- 'start-obs-idx': index of the first obs-markers not in the cache. None is
- up to date.
+ This class handle the tracking of changelog and obsstore update. It provide
+ data to performs incremental update (see the 'updatefrom' function for
+ details). This class can also detect stripping of the changelog or the
+ obsstore and can reset the cache in this cache (see the 'clear' function
+ for details).
"""
- # XXX ideally, this function would return a bounded amount of changeset and
- # obsmarkers and the associated new cache key. Otherwise we are exposed to
- # a race condition between the time the cache is updated and the new cache
- # key is computed. (however, we do not want to compute the full new cache
- # key in all case because we want to skip reading the obsstore content. We
- # could have a smarter implementation here.
+ # default key used for an empty cache
+ #
+ # The cache key covering the changesets and obsmarkers content
#
- # In pratice the cache is only updated after each transaction within a
- # lock. So we should be fine. We could enforce this with a new repository
- # requirement (or fix the race, that is not too hard).
- invalid = (False, 0, 0)
- if key is None:
- return invalid
+ # The cache key parts are:
+ # - tip-rev,
+ # - tip-node,
+ # - obsstore-length (nb markers),
+ # - obsstore-file-size (in bytes),
+ # - obsstore "cache key"
+ emptykey = (node.nullrev, node.nullid, 0, 0, node.nullid)
+ _cachename = None # used for error message
+
+ def __init__(self):
+ super(dualsourcecache, self).__init__()
+ self._cachekey = None
+
+ def _updatefrom(self, repo, revs, obsmarkers):
+ """override this method to update your cache data incrementally
+
+ revs: list of new revision in the changelog
+ obsmarker: list of new obsmarkers in the obsstore
+ """
+ raise NotImplementedError
+
+ 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.
+ """
+ # /!\ IMPORTANT /!\
+ # You must overide this method to actually
+ if reset:
+ self._cachekey = self.emptykey if reset else None
+ else:
+ self._cachekey = None
+
+ def load(self, repo):
+ """Load data from disk
+
+ Do not forget to restore the "cachekey" attribute while doing so.
+ """
+ raise NotImplementedError
+
+ # Useful public function (no need to override them)
+
+ def uptodate(self, repo):
+ """return True if the cache content is up to date False otherwise
+
+ This method can be used to detect of the cache is lagging behind new
+ data in either changelog or obsstore.
+ """
+ if self._cachekey is None:
+ self.load(repo)
+ status = self._checkkey(repo.changelog, repo.obsstore)
+ return (status is not None
+ and status[0] == self._cachekey[0] # tiprev
+ and status[1] == self._cachekey[3]) # obssize
+
+ 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)
+
+ assert repo.filtername is None
+ cl = repo.changelog
+
+ upgrade = self._upgradeneeded(repo)
+ if upgrade is None:
+ return
+
+ reset, revs, obsmarkers, obskeypair = upgrade
+ if reset or self._cachekey is None:
+ repo.ui.log('evoext-cache', 'strip detected, %s cache reset\n' % self._cachename)
+ self.clear(reset=True)
+
+ starttime = timer()
+ self._updatefrom(repo, revs, obsmarkers)
+ duration = timer() - starttime
+ repo.ui.log('evoext-cache', 'updated %s in %.4f seconds (%sr, %so)\n',
+ self._cachename, duration, len(revs), len(obsmarkers))
- ### Is the cache valid ?
- keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
- # check for changelog strip
- cl = repo.changelog
- tiprev = len(cl) - 1
- if (tiprev < keytiprev
- or cl.node(keytiprev) != keytipnode):
- return invalid
- # check for obsstore strip
- obssize, obskey = repo.obsstore.cachekey(index=keyobssize)
- if obskey != keyobskey:
- return invalid
+ # update the key from the new data
+ key = list(self._cachekey)
+ if revs:
+ key[0] = len(cl) - 1
+ key[1] = cl.node(key[0])
+ if obsmarkers:
+ key[2] += len(obsmarkers)
+ key[3], key[4] = obskeypair
+ self._cachekey = tuple(key)
+
+ # from here, there are internal function only
+
+ def _checkkey(self, changelog, obsstore):
+ """internal function"""
+ key = self._cachekey
+ if key is None:
+ return None
+
+ ### Is the cache valid ?
+ keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
+ # check for changelog strip
+ tiprev = len(changelog) - 1
+ if (tiprev < keytiprev
+ or changelog.node(keytiprev) != keytipnode):
+ return None
+ # check for obsstore strip
+ obssize, obskey = obsstore.cachekey(index=keyobssize)
+ if obskey != keyobskey:
+ return None
+ if obssize != keyobssize:
+ # we want to return the obskey for the new size
+ __, obskey = obsstore.cachekey(index=obssize)
+ return tiprev, obssize, obskey
+
+ def _upgradeneeded(self, repo):
+ """return (valid, start-rev, start-obs-idx)
+
+ 'valid': is "False" if older cache value needs invalidation,
+
+ 'start-rev': first revision not in the cache. None if cache is up to date,
+
+ 'start-obs-idx': index of the first obs-markers not in the cache. None is
+ up to date.
+ """
- ### cache is valid, is there anything to update
+ # We need to ensure we use the same changelog and obsstore through the
+ # processing. Otherwise some invalidation could update the object and their
+ # content after we computed the cache key.
+ cl = repo.changelog
+ obsstore = repo.obsstore
+ key = self._cachekey
+
+ reset = False
- # any new changesets ?
- startrev = None
- if keytiprev < tiprev:
- startrev = keytiprev + 1
+ status = self._checkkey(cl, obsstore)
+ if status is None:
+ reset = True
+ key = self.emptykey
+ obssize, obskey = obsstore.cachekey()
+ tiprev = len(cl) - 1
+ else:
+ tiprev, obssize, obskey = status
+
+ keytiprev, keytipnode, keyobslength, keyobssize, keyobskey = key
+
+ if not reset and keytiprev == tiprev and keyobssize == obssize:
+ return None # nothing to upgrade
- # any new markers
- startidx = None
- if keyobssize < obssize:
- startidx = keyobslength
+ ### cache is valid, is there anything to update
+
+ # any new changesets ?
+ revs = ()
+ if keytiprev < tiprev:
+ revs = list(cl.revs(start=keytiprev + 1, stop=tiprev))
- return True, startrev, startidx
+ # any new markers
+ markers = ()
+ if keyobssize < obssize:
+ # XXX Three are a small race change here. Since the obsstore might have
+ # move forward between the time we computed the cache key and we access
+ # the data. To fix this we need so "up to" argument when fetching the
+ # markers here. Otherwise we might return more markers than covered by
+ # the cache key.
+ #
+ # In pratice the cache is only updated after each transaction within a
+ # lock. So we should be fine. We could enforce this with a new repository
+ # requirement (or fix the race, that is not too hard).
+ markers = markersfrom(obsstore, keyobssize, keyobslength)
-class obscache(object):
+ return reset, revs, markers, (obssize, obskey)
+
+
+class obscache(dualsourcecache):
"""cache the "does a rev" is the precursors of some obsmarkers data
This is not directly holding the "is this revision obsolete" information,
@@ -197,16 +358,12 @@
_filepath = 'cache/evoext-obscache-00'
_headerformat = '>q20sQQ20s'
+ _cachename = 'evo-ext-obscache' # used for error message
+
def __init__(self, repo):
+ super(obscache, self).__init__()
+ self._ondiskkey = None
self._vfs = repo.vfs
- # The cache key parts are"
- # - tip-rev,
- # - tip-node,
- # - obsstore-length (nb markers),
- # - obsstore-file-size (in bytes),
- # - obsstore "cache key"
- self._cachekey = None
- self._ondiskkey = None
self._data = bytearray()
def get(self, rev):
@@ -215,90 +372,56 @@
Make sure the cache has been updated to match the repository content before using it"""
return self._data[rev]
- def clear(self):
+ def clear(self, reset=False):
"""invalidate the cache content"""
- self._cachekey = None
+ super(obscache, self).clear(reset=reset)
self._data = bytearray()
- def uptodate(self, repo):
- if self._cachekey is None:
- self.load(repo)
- valid, startrev, startidx = upgradeneeded(repo, self._cachekey)
- return (valid and startrev is None and startidx is None)
+ def _updatefrom(self, repo, revs, obsmarkers):
+ if revs:
+ self._updaterevs(repo, revs)
+ if obsmarkers:
+ self._updatemarkers(repo, obsmarkers)
+
+ def _updaterevs(self, repo, revs):
+ """update the cache with new revisions
+
+ Newly added changeset might be affected by obsolescence markers
+ we already have locally. So we needs to have some global
+ knowledge about the markers to handle that question.
+
+ Right now this requires parsing all markers in the obsstore. We could
+ imagine using various optimisation (eg: another cache, network
+ exchange, etc).
- def update(self, repo):
- """Iteratively update the cache with new repository data"""
- # If we do not have any data, try loading from disk
- if self._cachekey is None:
- self.load(repo)
+ A possible approach to this is to build a set of all node used as
+ precursors in `obsstore._obscandidate`. If markers are not loaded yet,
+ we could initialize it by doing a quick scan through the obsstore data
+ and filling a (pre-sized) set. Doing so would be much faster than
+ parsing all the obsmarkers since we would access less data, not create
+ any object beside the nodes and not have to decode any complex data.
- valid, startrev, startidx = upgradeneeded(repo, self._cachekey)
- if not valid:
- self.clear()
-
- if startrev is None and startidx is None:
- return
-
- # process the new changesets
+ For now we stick to the simpler approach of paying the
+ performance cost on new changesets.
+ """
+ node = repo.changelog.node
+ succs = repo.obsstore.successors
+ for r in revs:
+ if node(r) in succs:
+ val = 1
+ else:
+ val = 0
+ self._data.append(val)
cl = repo.changelog
- if startrev is not None:
- node = cl.node
- # Note:
- #
- # Newly added changeset might be affected by obsolescence markers
- # we already have locally. So we needs to have soem global
- # knowledge about the markers to handle that question. Right this
- # requires parsing all markers in the obsstore. However, we could
- # imagine using various optimisation (eg: bloom filter, other on
- # disk cache) to remove this full parsing.
- #
- # For now we stick to the simpler approach or paying the
- # performance cost on new changesets.
- succs = repo.obsstore.successors
- for r in cl.revs(startrev):
- if node(r) in succs:
- val = 1
- else:
- val = 0
- self._data.append(val)
assert len(self._data) == len(cl), (len(self._data), len(cl))
- # process the new obsmarkers
- if startidx is not None:
- rev = cl.nodemap.get
- markers = repo.obsstore._all
- # Note:
- #
- # There are no actually needs to load the full obsstore here,
- # since we only read the latest ones. We do it for simplicity in
- # the first implementation. Loading the full obsstore has a
- # performance cost and should go away in this case too. We have
- # two simples options for that:
- #
- # 1) provide and API to start reading markers from a byte offset
- # (we have that data in the cache key)
- #
- # 2) directly update the cache at a lower level, in the code
- # responsible for adding a markers.
- #
- # Option 2 is probably a bit more invasive, but more solid on the long run
-
- for i in xrange(startidx, len(repo.obsstore)):
- r = rev(markers[i][0])
- # If markers affect a newly added nodes, it would have been
- # caught in the previous loop, (so we skip < startrev)
- if r is not None and (startrev is None or r < startrev):
- self._data[r] = 1
-
- assert repo._currentlock(repo._lockref) is not None
- # XXX note that there are a potential race condition here, since the
- # repo "might" have changed side the cache update above. However, this
- # code will only be running in a lock so we ignore the issue for now.
- #
- # To work around this, 'upgradeneeded' should return a bounded amount
- # of changeset and markers to read with their associated cachekey. see
- # 'upgradeneeded' for detail.
- self._cachekey = getcachekey(repo)
+ def _updatemarkers(self, repo, obsmarkers):
+ """update the cache with new markers"""
+ rev = repo.changelog.nodemap.get
+ for m in obsmarkers:
+ r = rev(m[0])
+ if r is not None:
+ self._data[r] = 1
def save(self, repo):
"""save the data to disk"""
@@ -319,7 +442,7 @@
data = repo.vfs.tryread(self._filepath)
if not data:
- self._cachekey = emptykey
+ self._cachekey = self.emptykey
self._data = bytearray()
else:
headersize = struct.calcsize(self._headerformat)
@@ -339,7 +462,7 @@
if notpublic:
obscache = repo.obsstore.obscache
# Since we warm the cache at the end of every transaction, the cache
- # should be up to date. However a non-enabled client might have touced
+ # should be up to date. However a non-enabled client might have touched
# the repository.
#
# Updating the cache without a lock is sloppy, so we fallback to the
@@ -348,17 +471,18 @@
#
# With the current implementation updating the cache will requires to
# load the obsstore anyway. Once loaded, hitting the obsstore directly
- # will be about as fast..
+ # will be about as fast...
if not obscache.uptodate(repo):
if repo.currenttransaction() is None:
- repo.ui.log('evoext-obscache',
+ repo.ui.log('evoext-cache',
'obscache is out of date, '
'falling back to slower obsstore version\n')
repo.ui.debug('obscache is out of date')
return orig(repo)
else:
- # If a transaction is open, it is worthwhile to update and use the
- # cache as it will be written on disk when the transaction close.
+ # If a transaction is open, it is worthwhile to update and use
+ # the cache, the lock prevent race and it will be written on
+ # disk when the transaction close.
obscache.update(repo)
isobs = obscache.get
for r in notpublic:
@@ -381,6 +505,7 @@
def destroyed(self):
if 'obsstore' in vars(self):
self.obsstore.obscache.clear()
+ super(obscacherepo, self).destroyed()
def transaction(self, *args, **kwargs):
tr = super(obscacherepo, self).transaction(*args, **kwargs)
@@ -391,11 +516,10 @@
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 saving
- # logic.
+ # 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)
--- a/hgext3rd/evolve/obsdiscovery.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/evolve/obsdiscovery.py Thu May 18 23:51:10 2017 +0200
@@ -24,8 +24,10 @@
import hashlib
import heapq
+import os
import sqlite3
import struct
+import time
import weakref
from mercurial import (
@@ -36,6 +38,7 @@
localrepo,
node,
obsolete,
+ pycompat,
scmutil,
setdiscovery,
util,
@@ -46,10 +49,21 @@
from . import (
exthelper,
+ obscache,
utility,
stablerange,
)
+# 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
+
_pack = struct.pack
_unpack = struct.unpack
_calcsize = struct.calcsize
@@ -214,6 +228,7 @@
initialsamplesize=100,
fullsamplesize=200):
missing = set()
+ starttime = timer()
heads = local.revs('heads(%ld)', probeset)
local.stablerange.warmup(local)
@@ -241,6 +256,7 @@
entry = (h, 0)
addentry(entry)
+ local.obsstore.rangeobshashcache.update(local)
querycount = 0
ui.progress(_("comparing obsmarker with other"), querycount)
overflow = []
@@ -300,6 +316,12 @@
ui.progress(_("comparing obsmarker with other"), querycount)
ui.progress(_("comparing obsmarker with other"), None)
local.obsstore.rangeobshashcache.save(local)
+ duration = timer() - starttime
+ logmsg = ('obsdiscovery, %d/%d mismatch'
+ ' - %d obshashrange queries in %.4f seconds\n')
+ logmsg %= (len(missing), len(probeset), querycount, duration)
+ ui.log('evoext-obsdiscovery', logmsg)
+ ui.debug(logmsg)
return sorted(missing)
def _queryrange(ui, repo, remote, allentries):
@@ -342,6 +364,7 @@
linetemplate = '%12d %12s %12d %12d %12d %12s\n'
headertemplate = linetemplate.replace('d', 's')
ui.status(headertemplate % headers)
+ repo.obsstore.rangeobshashcache.update(repo)
for r in ranges:
d = (r[0],
s(cl.node(r[0])),
@@ -392,10 +415,11 @@
_sqliteschema = [
"""CREATE TABLE meta(schemaversion INTEGER NOT NULL,
+ tiprev INTEGER NOT NULL,
+ tipnode BLOB NOT NULL,
nbobsmarker INTEGER NOT NULL,
- obstipdata BLOB NOT NULL,
- tiprev INTEGER NOT NULL,
- tipnode BLOB NOT NULL
+ obssize BLOB NOT NULL,
+ obskey BLOB NOT NULL
);""",
"""CREATE TABLE obshashrange(rev INTEGER NOT NULL,
idx INTEGER NOT NULL,
@@ -404,53 +428,132 @@
"CREATE INDEX range_index ON obshashrange(rev, idx);",
]
_queryexist = "SELECT name FROM sqlite_master WHERE type='table' AND name='meta';"
-_newmeta = """INSERT INTO meta (schemaversion, nbobsmarker, obstipdata, tiprev, tipnode)
- VALUES (?,?,?,?,?);"""
+_clearmeta = """DELETE FROM meta;"""
+_newmeta = """INSERT INTO meta (schemaversion, tiprev, tipnode, nbobsmarker, obssize, obskey)
+ VALUES (?,?,?,?,?,?);"""
_updateobshash = "INSERT INTO obshashrange(rev, idx, obshash) VALUES (?,?,?);"
-_querymeta = "SELECT schemaversion, nbobsmarker, obstipdata, tiprev, tipnode FROM meta;"
+_querymeta = "SELECT schemaversion, tiprev, tipnode, nbobsmarker, obssize, obskey FROM meta;"
_queryobshash = "SELECT obshash FROM obshashrange WHERE (rev = ? AND idx = ?);"
-class _obshashcache(dict):
+_reset = "DELETE FROM obshashrange;"
+
+class _obshashcache(obscache.dualsourcecache):
- _schemaversion = 0
+ _schemaversion = 1
+
+ _cachename = 'evo-ext-obshashrange' # used for error message
def __init__(self, repo):
super(_obshashcache, self).__init__()
- self._path = repo.vfs.join('cache/evoext_obshashrange_v0.sqlite')
+ self._vfs = repo.vfs
+ self._path = repo.vfs.join('cache/evoext_obshashrange_v1.sqlite')
self._new = set()
self._valid = True
self._repo = weakref.ref(repo.unfiltered())
# cache status
self._ondiskcachekey = None
+ self._data = {}
- def clear(self):
- self._valid = False
- super(_obshashcache, self).clear()
+ def clear(self, reset=False):
+ super(_obshashcache, self).clear(reset=reset)
+ self._data.clear()
self._new.clear()
+ if reset:
+ self._valid = False
+ if '_con' in vars(self):
+ del self._con
def get(self, rangeid):
- value = super(_obshashcache, self).get(rangeid)
+ # revision should be covered by the tiprev
+ #
+ # XXX there are issue with cache warming, we hack around it for now
+ if not getattr(self, '_updating', False):
+ if self._cachekey[0] < rangeid[0]:
+ msg = ('using unwarmed obshashrangecache (%s %s)'
+ % (rangeid[0], self._cachekey[0]))
+ raise error.ProgrammingError(msg)
+
+ value = self._data.get(rangeid)
if value is None and self._con is not None:
nrange = (rangeid[0], rangeid[1])
obshash = self._con.execute(_queryobshash, nrange).fetchone()
if obshash is not None:
value = obshash[0]
+ self._data[rangeid] = value
return value
def __setitem__(self, rangeid, obshash):
self._new.add(rangeid)
- super(_obshashcache, self).__setitem__(rangeid, obshash)
+ self._data[rangeid] = obshash
+
+ def _updatefrom(self, repo, revs, obsmarkers):
+ """override this method to update your cache data incrementally
+
+ revs: list of new revision in the changelog
+ obsmarker: list of new obsmarkers in the obsstore
+ """
+ # XXX for now, we'll not actually update the cache, but we'll be
+ # smarter at invalidating it.
+ #
+ # 1) new revisions does not get their entry updated (not update)
+ # 2) if we detect markers affecting non-new revision we reset the cache
+
+ self._updating = True
+
+ setrevs = set(revs)
+ rev = repo.changelog.nodemap.get
+ # if we have a new markers affecting a node already covered by the
+ # cache, we must abort.
+ affected = set()
+ for m in obsmarkers:
+ # check successors and parent
+ for l in (m[1], m[5]):
+ if l is None:
+ continue
+ for p in l:
+ r = rev(p)
+ if r is not None and r not in setrevs:
+ # XXX should check < min(setrevs) or tiprevs
+ affected.add(r)
- def _cachekey(self, repo):
- # XXX for now the cache is very volatile, but this is still a win
- nbobsmarker = len(repo.obsstore._all)
- if nbobsmarker:
- tipdata = obsolete._fm1encodeonemarker(repo.obsstore._all[-1])
- else:
- tipdata = node.nullid
- tiprev = len(repo.changelog) - 1
- tipnode = repo.changelog.node(tiprev)
- return (self._schemaversion, nbobsmarker, tipdata, tiprev, tipnode)
+ if affected:
+ repo.ui.log('evoext-cache', 'obshashcache reset - '
+ 'new markers affect cached ranges\n')
+ # XXX the current reset is too strong we could just drop the affected range
+ con = self._con
+ if con is not None:
+ con.execute(_reset)
+ # rewarm the whole cache
+ stop = self._cachekey[0] # tiprev
+ if revs:
+ stop = max(revs)
+ if 0 <= stop:
+ revs = repo.changelog.revs(stop=stop)
+
+ # warm the cache for the new revs
+ for r in revs:
+ _obshashrange(repo, (r, 0))
+
+ del self._updating
+
+ @property
+ def _fullcachekey(self):
+ return (self._schemaversion, ) + self._cachekey
+
+ def load(self, repo):
+ if self._con is None:
+ self._cachekey = self.emptykey
+ self._ondiskcachekey = self.emptykey
+ assert self._cachekey is not None
+
+ def _db(self):
+ try:
+ util.makedirs(self._vfs.dirname(self._path))
+ except OSError:
+ return None
+ con = sqlite3.connect(self._path)
+ con.text_factory = str
+ return con
@util.propertycache
def _con(self):
@@ -459,25 +562,27 @@
repo = self._repo()
if repo is None:
return None
- cachekey = self._cachekey(repo)
- con = sqlite3.connect(self._path)
- con.text_factory = str
+ con = self._db()
+ if con is None:
+ return None
cur = con.execute(_queryexist)
if cur.fetchone() is None:
self._valid = False
return None
meta = con.execute(_querymeta).fetchone()
- if meta != cachekey:
+ if meta is None or meta[0] != self._schemaversion:
self._valid = False
return None
- self._ondiskcachekey = meta
+ self._cachekey = self._ondiskcachekey = meta[1:]
return con
def save(self, repo):
+ if self._cachekey is None:
+ return
+ if self._cachekey == self._ondiskcachekey and not self._new:
+ return
repo = repo.unfiltered()
try:
- if not self._new:
- return
with repo.lock():
self._save(repo)
except error.LockError:
@@ -493,32 +598,38 @@
if '_con' in vars(self):
del self._con
- con = sqlite3.connect(self._path)
- con.text_factory = str
+ con = self._db()
+ if con is None:
+ repo.ui.log('evoext-cache', 'unable to write obshashrange cache'
+ ' - cannot create database')
+ return
with con:
for req in _sqliteschema:
con.execute(req)
- con.execute(_newmeta, self._cachekey(repo))
+ con.execute(_newmeta, self._fullcachekey)
else:
con = self._con
if self._ondiskcachekey is not None:
meta = con.execute(_querymeta).fetchone()
- if meta != self._ondiskcachekey:
+ if meta[1:] != self._ondiskcachekey:
# drifting is currently an issue because this means another
# process might have already added the cache line we are about
# to add. This will confuse sqlite
msg = _('obshashrange cache: skipping write, '
'database drifted under my feet\n')
- data = (meta[2], meta[1], self._ondisktiprev, self._ondisktipnode)
+ data = (meta[2], meta[1], self._ondiskcachekey[0], self._ondiskcachekey[1])
repo.ui.warn(msg)
- data = ((rangeid[0], rangeid[1], self[rangeid]) for rangeid in self._new)
+ return
+ data = ((rangeid[0], rangeid[1], self.get(rangeid)) for rangeid in self._new)
con.executemany(_updateobshash, data)
- cachekey = self._cachekey(repo)
+ cachekey = self._fullcachekey
+ con.execute(_clearmeta) # remove the older entry
con.execute(_newmeta, cachekey)
con.commit()
self._new.clear()
- self._ondiskcachekey = cachekey
+ self._ondiskcachekey = self._cachekey
+ self._valid = True
@eh.wrapfunction(obsolete.obsstore, '_addmarkers')
def _addmarkers(orig, obsstore, *args, **kwargs):
@@ -549,10 +660,31 @@
class obshashrepo(repo.__class__):
@localrepo.unfilteredmethod
def destroyed(self):
- if 'stablerange' in vars(self):
- del self.stablerange
+ if 'obsstore' in vars(self):
+ self.obsstore.rangeobshashcache.clear()
super(obshashrepo, self).destroyed()
+ def transaction(self, *args, **kwargs):
+ tr = super(obshashrepo, self).transaction(*args, **kwargs)
+ reporef = weakref.ref(self)
+
+ def _warmcache(tr):
+ repo = reporef()
+ if repo is None:
+ return
+ if not repo.ui.configbool('experimental', 'obshashrange', False):
+ 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.rangeobshashcache.update(repo)
+ self.obsstore.rangeobshashcache.save(repo)
+
+ tr.addpostclose('warmcache-20-obscacherange', _warmcache)
+ return tr
+
repo.__class__ = obshashrepo
### wire protocol commands
@@ -570,6 +702,7 @@
if maxrev is not None:
repo.stablerange.warmup(repo, upto=maxrev)
result = []
+ repo.obsstore.rangeobshashcache.update(repo)
for r in ranges:
if r[0] is None:
result.append(node.wdirid)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hgext3rd/evolve/obshistory.py Thu May 18 23:51:10 2017 +0200
@@ -0,0 +1,357 @@
+# Code dedicated to display and exploration of the obsolescence history
+#
+# This module content aims at being upstreamed enventually.
+#
+# 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 mercurial import (
+ cmdutil,
+ commands,
+ error,
+ graphmod,
+ node as nodemod,
+ scmutil,
+)
+
+from mercurial.i18n import _
+
+from . import (
+ exthelper,
+)
+
+eh = exthelper.exthelper()
+
+@eh.command(
+ 'olog',
+ [('G', 'graph', True, _("show the revision DAG")),
+ ('r', 'rev', [], _('show the specified revision or revset'), _('REV'))
+ ] + commands.formatteropts,
+ _('hg olog [OPTION]... [REV]'))
+def cmdobshistory(ui, repo, *revs, **opts):
+ """show the obsolescence history of the specified revisions.
+
+ If no revision range is specified, we display the log for the current
+ working copy parent.
+
+ By default this command prints the selected revisions and all its
+ precursors. For precursors pointing on existing revisions in the repository,
+ it will display revisions node id, revision number and the first line of the
+ description. For precursors pointing on non existing revisions in the
+ repository (that can happen when exchanging obsolescence-markers), display
+ only the node id.
+
+ In both case, for each node, its obsolescence marker will be displayed with
+ the obsolescence operation (rewritten or pruned) in addition of the user and
+ date of the operation.
+
+ The output is a graph by default but can deactivated with the option '--no-
+ graph'.
+
+ 'o' is a changeset, '@' is a working directory parent, 'x' is obsolete,
+ and '+' represents a fork where the changeset from the lines below is a
+ parent of the 'o' merge on the same line.
+
+ Paths in the DAG are represented with '|', '/' and so forth.
+
+ Returns 0 on success.
+ """
+ revs = list(revs) + opts['rev']
+ if not revs:
+ revs = ['.']
+ revs = scmutil.revrange(repo, revs)
+
+ if opts['graph']:
+ return _debugobshistorygraph(ui, repo, revs, opts)
+
+ fm = ui.formatter('debugobshistory', opts)
+ revs.reverse()
+ _debugobshistorysingle(fm, repo, revs)
+
+ fm.end()
+
+class obsmarker_printer(cmdutil.changeset_printer):
+ """show (available) information about a node
+
+ We display the node, description (if available) and various information
+ about obsolescence markers affecting it"""
+
+ def show(self, ctx, copies=None, matchfn=None, **props):
+ if self.buffered:
+ self.ui.pushbuffer(labeled=True)
+
+ changenode = ctx.node()
+
+ fm = self.ui.formatter('debugobshistory', props)
+ _debugobshistorydisplaynode(fm, self.repo, changenode)
+
+ succs = self.repo.obsstore.successors.get(changenode, ())
+
+ markerfm = fm.nested("debugobshistory.markers")
+ for successor in sorted(succs):
+ _debugobshistorydisplaymarker(markerfm, self.repo, successor)
+ markerfm.end()
+
+ markerfm.plain('\n')
+
+ self.hunk[ctx.node()] = self.ui.popbuffer()
+ else:
+ ### graph output is buffered only
+ msg = 'cannot be used outside of the graphlog (yet)'
+ raise error.ProgrammingError(msg)
+
+ def flush(self, ctx):
+ ''' changeset_printer has some logic around buffering data
+ in self.headers that we don't use
+ '''
+ pass
+
+class missingchangectx(object):
+ ''' a minimal object mimicking changectx for change contexts
+ references by obs markers but not available locally '''
+
+ def __init__(self, repo, nodeid):
+ self._repo = repo
+ self._node = nodeid
+
+ def node(self):
+ return self._node
+
+ def obsolete(self):
+ # If we don't have it locally, it's obsolete
+ return True
+
+def cyclic(graph):
+ """Return True if the directed graph has a cycle.
+ The graph must be represented as a dictionary mapping vertices to
+ iterables of neighbouring vertices. For example:
+
+ >>> cyclic({1: (2,), 2: (3,), 3: (1,)})
+ True
+ >>> cyclic({1: (2,), 2: (3,), 3: (4,)})
+ False
+
+ Taken from: https://codereview.stackexchange.com/a/86067
+
+ """
+ visited = set()
+ o = object()
+ path = [o]
+ path_set = set(path)
+ stack = [iter(graph)]
+ while stack:
+ for v in sorted(stack[-1]):
+ if v in path_set:
+ path_set.remove(o)
+ return path_set
+ elif v not in visited:
+ visited.add(v)
+ path.append(v)
+ path_set.add(v)
+ stack.append(iter(graph.get(v, ())))
+ break
+ else:
+ path_set.remove(path.pop())
+ stack.pop()
+ return False
+
+def _obshistorywalker(repo, revs):
+ """ Directly inspired by graphmod.dagwalker,
+ walk the obs marker tree and yield
+ (id, CHANGESET, ctx, [parentinfo]) tuples
+ """
+
+ # Get the list of nodes and links between them
+ candidates, nodesucc, nodeprec = _obshistorywalker_links(repo, revs)
+
+ # Shown, set of nodes presents in items
+ shown = set()
+
+ def isvalidcandidate(candidate):
+ """ Function to filter candidates, check the candidate succ are
+ in shown set
+ """
+ return nodesucc.get(candidate, set()).issubset(shown)
+
+ # While we have some nodes to show
+ while candidates:
+
+ # Filter out candidates, returns only nodes with all their successors
+ # already shown
+ validcandidates = filter(isvalidcandidate, candidates)
+
+ # If we likely have a cycle
+ if not validcandidates:
+ cycle = cyclic(nodesucc)
+ assert cycle
+
+ # Then choose a random node from the cycle
+ breaknode = sorted(cycle)[0]
+ # And display it by force
+ repo.ui.debug('obs-cycle detected, forcing display of %s\n'
+ % nodemod.short(breaknode))
+ validcandidates = [breaknode]
+
+ # Display all valid candidates
+ for cand in sorted(validcandidates):
+ # Remove candidate from candidates set
+ candidates.remove(cand)
+ # And remove it from nodesucc in case of future cycle detected
+ try:
+ del nodesucc[cand]
+ except KeyError:
+ pass
+
+ shown.add(cand)
+
+ # Add the right changectx class
+ if cand in repo:
+ changectx = repo[cand]
+ else:
+ changectx = missingchangectx(repo, cand)
+
+ childrens = [(graphmod.PARENT, x) for x in nodeprec.get(cand, ())]
+ yield (cand, 'M', changectx, childrens)
+
+def _obshistorywalker_links(repo, revs):
+ """ Iterate the obs history tree starting from revs, traversing
+ each revision precursors recursively.
+ Return a tuple of:
+ - The list of node crossed
+ - The dictionnary of each node successors, values are a set
+ - The dictionnary of each node precursors, values are a list
+ """
+ precursors = repo.obsstore.precursors
+ nodec = repo.changelog.node
+
+ # Parents, set of parents nodes seen during walking the graph for node
+ nodesucc = dict()
+ # Childrens
+ nodeprec = dict()
+
+ nodes = [nodec(r) for r in revs]
+ seen = set(nodes)
+
+ # Iterate on each node
+ while nodes:
+ node = nodes.pop()
+
+ precs = precursors.get(node, ())
+
+ nodeprec[node] = []
+
+ for prec in sorted(precs):
+ precnode = prec[0]
+
+ # Mark node as prec successor
+ nodesucc.setdefault(precnode, set()).add(node)
+
+ # Mark precnode as node precursor
+ nodeprec[node].append(precnode)
+
+ # Add prec for future processing if not node already processed
+ if precnode not in seen:
+ seen.add(precnode)
+ nodes.append(precnode)
+
+ return sorted(seen), nodesucc, nodeprec
+
+def _debugobshistorygraph(ui, repo, revs, opts):
+ displayer = obsmarker_printer(ui, repo.unfiltered(), None, opts, buffered=True)
+ edges = graphmod.asciiedges
+ cmdutil.displaygraph(ui, repo, _obshistorywalker(repo.unfiltered(), revs), displayer, edges)
+
+def _debugobshistorysingle(fm, repo, revs):
+ """ Display the obsolescence history for a single revision
+ """
+ precursors = repo.obsstore.precursors
+ successors = repo.obsstore.successors
+ nodec = repo.changelog.node
+ nodes = [nodec(r) for r in revs]
+
+ seen = set(nodes)
+
+ while nodes:
+ ctxnode = nodes.pop()
+
+ _debugobshistorydisplaynode(fm, repo, ctxnode)
+
+ succs = successors.get(ctxnode, ())
+
+ markerfm = fm.nested("debugobshistory.markers")
+ for successor in sorted(succs):
+ _debugobshistorydisplaymarker(markerfm, repo, successor)
+ markerfm.end()
+
+ precs = precursors.get(ctxnode, ())
+ for p in sorted(precs):
+ # Only show nodes once
+ if p[0] not in seen:
+ seen.add(p[0])
+ nodes.append(p[0])
+
+def _debugobshistorydisplaynode(fm, repo, node):
+ if node in repo.unfiltered():
+ _debugobshistorydisplayctx(fm, repo.unfiltered()[node])
+ else:
+ _debugobshistorydisplaymissingctx(fm, node)
+
+def _debugobshistorydisplayctx(fm, ctx):
+ shortdescription = ctx.description().splitlines()[0]
+
+ fm.startitem()
+ fm.write('debugobshistory.node', '%s', str(ctx),
+ label="evolve.node")
+ fm.plain(' ')
+
+ fm.write('debugobshistory.rev', '(%d)', int(ctx),
+ label="evolve.rev")
+ fm.plain(' ')
+
+ fm.write('debugobshistory.shortdescription', '%s', shortdescription,
+ label="evolve.short_description")
+ fm.plain('\n')
+
+def _debugobshistorydisplaymissingctx(fm, nodewithoutctx):
+ hexnode = nodemod.short(nodewithoutctx)
+ fm.startitem()
+ fm.write('debugobshistory.node', '%s', hexnode,
+ label="evolve.node evolve.missing_change_ctx")
+ fm.plain('\n')
+
+def _debugobshistorydisplaymarker(fm, repo, marker):
+ succnodes = marker[1]
+ date = marker[4]
+ metadata = dict(marker[3])
+
+ fm.startitem()
+ fm.plain(' ')
+
+ # Detect pruned revisions
+ if len(succnodes) == 0:
+ verb = 'pruned'
+ else:
+ verb = 'rewritten'
+
+ fm.write('debugobshistory.verb', '%s', verb,
+ label="evolve.verb")
+ fm.plain(' by ')
+
+ fm.write('debugobshistory.marker_user', '%s', metadata['user'],
+ label="evolve.user")
+ fm.plain(' ')
+
+ fm.write('debugobshistory.marker_date', '(%s)', fm.formatdate(date),
+ label="evolve.date")
+
+ if len(succnodes) > 0:
+ fm.plain(' as ')
+
+ shortsnodes = (nodemod.short(succnode) for succnode in sorted(succnodes))
+ nodes = fm.formatlist(shortsnodes, 'debugobshistory.succnodes', sep=', ')
+ fm.write('debugobshistory.succnodes', '%s', nodes,
+ label="evolve.node")
+
+ fm.plain("\n")
--- a/hgext3rd/evolve/serveronly.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/evolve/serveronly.py Thu May 18 23:51:10 2017 +0200
@@ -17,6 +17,7 @@
from . import (
exthelper,
metadata,
+ obscache,
obsexchange,
)
except ValueError as exc:
@@ -27,6 +28,7 @@
from evolve import (
exthelper,
metadata,
+ obscache,
obsexchange,
)
@@ -36,6 +38,7 @@
buglink = metadata.buglink
eh = exthelper.exthelper()
+eh.merge(obscache.eh)
eh.merge(obsexchange.eh)
uisetup = eh.final_uisetup
extsetup = eh.final_extsetup
--- a/hgext3rd/evolve/stablerange.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/evolve/stablerange.py Thu May 18 23:51:10 2017 +0200
@@ -10,7 +10,9 @@
import collections
import heapq
import math
+import os
import sqlite3
+import time
import weakref
from mercurial import (
@@ -19,6 +21,7 @@
error,
localrepo,
node as nodemod,
+ pycompat,
scmutil,
util,
)
@@ -31,6 +34,16 @@
eh = exthelper.exthelper()
+# 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
+
##################################
### Stable topological sorting ###
##################################
@@ -263,6 +276,7 @@
#
# we use the revnumber as an approximation for depth
ui = repo.ui
+ starttime = timer()
if upto is None:
upto = len(cl) - 1
@@ -308,6 +322,10 @@
self._tiprev = upto
self._tipnode = cl.node(upto)
+ duration = timer() - starttime
+ repo.ui.log('evoext-cache', 'updated stablerange cache in %.4f seconds\n',
+ duration)
+
def depthrev(self, repo, rev):
repo = repo.unfiltered()
cl = repo.changelog
@@ -714,6 +732,7 @@
def __init__(self, repo):
super(sqlstablerange, self).__init__()
+ self._vfs = repo.vfs
self._path = repo.vfs.join('cache/evoext_stablerange_v0.sqlite')
self._cl = repo.unfiltered().changelog # (okay to keep an old one)
self._ondisktiprev = None
@@ -777,10 +796,20 @@
self._loaddepth()
return super(sqlstablerange, self)._inheritancepoint(*args, **kwargs)
+ def _db(self):
+ try:
+ util.makedirs(self._vfs.dirname(self._path))
+ except OSError:
+ return None
+ con = sqlite3.connect(self._path)
+ con.text_factory = str
+ return con
+
@util.propertycache
def _con(self):
- con = sqlite3.connect(self._path)
- con.text_factory = str
+ con = self._db()
+ if con is None:
+ return None
cur = con.execute(_queryexist)
if cur.fetchone() is None:
return None
@@ -810,8 +839,9 @@
if '_con' in vars(self):
del self._con
- con = sqlite3.connect(self._path)
- con.text_factory = str
+ con = self._db()
+ if con is None:
+ return
with con:
for req in _sqliteschema:
con.execute(req)
@@ -902,7 +932,7 @@
# new nodes !
repo.stablerange.warmup(repo)
- tr.addpostclose('warmcache-stablerange', _warmcache)
+ tr.addpostclose('warmcache-10-stablerange', _warmcache)
return tr
repo.__class__ = stablerangerepo
--- a/hgext3rd/topic/__init__.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/topic/__init__.py Thu May 18 23:51:10 2017 +0200
@@ -100,9 +100,13 @@
'topic.stack.summary.behindcount': 'cyan',
'topic.stack.summary.behinderror': 'red',
'topic.stack.summary.headcount.multiple': 'yellow',
+ # default color to help log output and thg
+ # (first pick I could think off, update as needed
+ 'log.topic': 'green_background',
+ 'topic.active': 'green',
}
-testedwith = '3.9'
+testedwith = '4.0.2 4.1.3 4.2'
def _contexttopic(self):
return self.extra().get(constants.extrakey, '')
@@ -157,6 +161,10 @@
if not isinstance(repo, localrepo.localrepository):
return # this can be a peer in the ssh case (puzzling)
+ if repo.ui.config('experimental', 'thg.displaynames', None) is None:
+ repo.ui.setconfig('experimental', 'thg.displaynames', 'topics',
+ source='topic-extension')
+
class topicrepo(repo.__class__):
def _restrictcapabilities(self, caps):
--- a/hgext3rd/topic/stack.py Wed May 03 13:23:36 2017 +0200
+++ b/hgext3rd/topic/stack.py Thu May 18 23:51:10 2017 +0200
@@ -15,6 +15,12 @@
trevs = repo.revs("topic(%s) - obsolete()", topic)
return _orderrevs(repo, trevs)
+def labelsgen(prefix, labelssuffix):
+ """ Takes a label prefix and a list of suffixes. Returns a string of the prefix
+ formatted with each suffix separated with a space.
+ """
+ return ' '.join(prefix % suffix for suffix in labelssuffix)
+
def showstack(ui, repo, topic, opts):
fm = ui.formatter('topicstack', opts)
prev = None
@@ -59,35 +65,44 @@
# super crude initial version
for idx, isentry, ctx in entries[::-1]:
+
+ states = []
+ iscurrentrevision = repo.revs('%d and parents()', ctx.rev())
+
+ if iscurrentrevision:
+ states.append('current')
+
if not isentry:
symbol = '^'
- state = 'base'
- elif repo.revs('%d and parents()', ctx.rev()):
+ # "base" is kind of a "ghost" entry
+ # skip other label for them (no current, no unstable)
+ states = ['base']
+ elif iscurrentrevision:
symbol = '@'
- state = 'current'
elif repo.revs('%d and unstable()', ctx.rev()):
symbol = '$'
- state = 'unstable'
+ states.append('unstable')
else:
symbol = ':'
- state = 'clean'
+ states.append('clean')
fm.startitem()
fm.data(isentry=isentry)
+
if idx is None:
fm.plain(' ')
else:
fm.write('topic.stack.index', 't%d', idx,
- label='topic.stack.index topic.stack.index.%s' % state)
+ label='topic.stack.index ' + labelsgen('topic.stack.index.%s', states))
fm.write('topic.stack.state.symbol', '%s', symbol,
- label='topic.stack.state topic.stack.state.%s' % state)
+ label='topic.stack.state ' + labelsgen('topic.stack.state.%s', states))
fm.plain(' ')
fm.write('topic.stack.desc', '%s', ctx.description().splitlines()[0],
- label='topic.stack.desc topic.stack.desc.%s' % state)
- fm.condwrite(state != 'clean' and idx is not None, 'topic.stack.state',
- ' (%s)', state,
- label='topic.stack.state topic.stack.state.%s' % state)
+ label='topic.stack.desc ' + labelsgen('topic.stack.desc.%s', states))
+ fm.condwrite(states != ['clean'] and idx is not None, 'topic.stack.state',
+ ' (%s)', fm.formatlist(states, 'topic.stack.state'),
+ label='topic.stack.state ' + labelsgen('topic.stack.state.%s', states))
fm.plain('\n')
- fm.end()
+ fm.end()
def stackdata(repo, topic):
"""get various data about a stack
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-check-commit.t Thu May 18 23:51:10 2017 +0200
@@ -0,0 +1,22 @@
+#require test-repo
+
+Enable obsolescence to avoid the warning issue when obsmarker are found
+
+ $ cat << EOF >> $HGRCPATH
+ > [experimental]
+ > evolution=all
+ > EOF
+
+Go back in the hg repo
+
+ $ cd $TESTDIR/..
+
+ $ for node in `hg log --rev 'not public() and ::. and not desc("# no-check-commit")' --template '{node|short}\n'`; do
+ > hg export $node | ${RUNTESTDIR}/../contrib/check-commit > ${TESTTMP}/check-commit.out
+ > if [ $? -ne 0 ]; then
+ > echo "Revision $node does not comply with rules"
+ > echo '------------------------------------------------------'
+ > cat ${TESTTMP}/check-commit.out
+ > echo
+ > fi
+ > done
--- a/tests/test-check-setup-manifest.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-#require test-repo
-
- $ checkcm() {
- > if ! (which check-manifest > /dev/null); then
- > echo skipped: missing tool: check-manifest;
- > exit 80;
- > fi;
- > };
- $ checkcm
- $ cat << EOF >> $HGRCPATH
- > [experimental]
- > evolution=all
- > EOF
-
-Run check manifest:
-
- $ cd $TESTDIR/..
- $ check-manifest
- lists of files in version control and sdist match
--- a/tests/test-discovery-obshashrange.t Wed May 03 13:23:36 2017 +0200
+++ b/tests/test-discovery-obshashrange.t Thu May 18 23:51:10 2017 +0200
@@ -6,6 +6,9 @@
$ cat << EOF >> $HGRCPATH
> [extensions]
> hgext3rd.evolve =
+ > blackbox =
+ > [defaults]
+ > blackbox = -l 100
> [experimental]
> obshashrange=1
> verbose-obsolescence-exchange=1
@@ -17,7 +20,7 @@
> EOF
$ getid() {
- > hg log --hidden --template '{node}\n' --rev "$1"
+ > hg log --hidden --template '{node}\n' --rev "$1" --config 'extensions.blackbox=!'
> }
$ hg init server
@@ -27,6 +30,31 @@
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd server
$ hg debugbuilddag '.+7'
+ $ hg blackbox
+ * @0000000000000000000000000000000000000000 (*)> serve --stdio (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugbuilddag .+7 (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated served branch cache in *.???? seconds (glob)
+ * @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 (*)> updated served branch cache in *.???? seconds (glob)
+ * @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 (*)> updated served branch cache in *.???? seconds (glob)
+ * @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 (*)> updated served branch cache in *.???? seconds (glob)
+ * @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 (*)> 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)
+ * @0000000000000000000000000000000000000000 (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
$ hg log -G
o 7 4de32a90b66c r7 tip
|
@@ -57,6 +85,39 @@
dddddddddddddddddddddddddddddddddddddddd c8d03c1b5e94af74b772900c58259d2e08917735 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 4de32a90b66cd083ebf3c00b41277aa7abca51dd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ $ hg blackbox
+ * @0000000000000000000000000000000000000000 (*)> log -G (glob)
+ * @0000000000000000000000000000000000000000 (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
+ * @0000000000000000000000000000000000000000 (*)> log -G exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 66f7d451a68b85ed82ff5fcc254daf50c74144bd (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (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)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 01241442b3c2bf3211e593b549c655ea65b295e3 (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 01241442b3c2bf3211e593b549c655ea65b295e3 exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete dddddddddddddddddddddddddddddddddddddddd c8d03c1b5e94af74b772900c58259d2e08917735 (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete dddddddddddddddddddddddddddddddddddddddd c8d03c1b5e94af74b772900c58259d2e08917735 exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 4de32a90b66cd083ebf3c00b41277aa7abca51dd (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 4de32a90b66cd083ebf3c00b41277aa7abca51dd exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
$ hg debugobshashrange --subranges --rev tip
rev node index size depth obshash
7 4de32a90b66c 0 8 8 38d1e7ad86ea
@@ -88,10 +149,30 @@
added 5 changesets with 0 changes to 0 files
3 new obsolescence markers
(run 'hg update' to get a working copy)
+ $ hg -R ../server blackbox
+ * @0000000000000000000000000000000000000000 (*)> debugobshashrange --subranges --rev tip (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated stablerange cache in *.???? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobshashrange --subranges --rev tip exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> serve --stdio (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> blackbox (glob)
+ $ rm ../server/.hg/blackbox.log
$ hg -R ../server/ debugobsolete --rev ::4 | sort
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 66f7d451a68b85ed82ff5fcc254daf50c74144bd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 01241442b3c2bf3211e593b549c655ea65b295e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ $ rm ../server/.hg/blackbox.log
+ $ hg blackbox
+ * @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 (*)> 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)
+ * @0000000000000000000000000000000000000000 (*)> 5 incoming changes - new heads: bebd167eb94d (glob)
+ * @0000000000000000000000000000000000000000 (*)> pull --rev 4 exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
$ hg debugobsolete | sort
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 66f7d451a68b85ed82ff5fcc254daf50c74144bd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 01241442b3c2bf3211e593b549c655ea65b295e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -106,17 +187,75 @@
$ hg add foo
$ hg commit -m foo
$ hg debugobsolete ffffffffffffffffffffffffffffffffffffffff `getid '.'`
- $ hg push -f
+ $ hg push -f --debug
pushing to ssh://user@dummy/server
+ running python "*/dummyssh" user@dummy 'hg -R server serve --stdio' (glob)
+ sending hello command
+ sending between command
+ remote: 532
+ remote: capabilities: _evoext_getbundle_obscommon _evoext_obshash_0 _evoext_obshash_1 _evoext_obshashrange_v0 _evoext_pullobsmarkers_0 _evoext_pushobsmarkers_0 batch branchmap bundle2=HG20%0Achangegroup%3D01%2C02%0Adigests%3Dmd5%2Csha1%2Csha512%0Aerror%3Dabort%2Cunsupportedcontent%2Cpushraced%2Cpushkey%0Ahgtagsfnodes%0Alistkeys%0Aobsmarkers%3DV0%2CV1%0Apushkey%0Aremote-changegroup%3Dhttp%2Chttps changegroupsubset getbundle httpheader=1024 known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
+ remote: 1
+ preparing listkeys for "phases"
+ sending listkeys command
+ received listkey for "phases": 58 bytes
+ query 1; heads
+ sending batch command
searching for changes
+ taking quick initial sample
+ query 2; still undecided: 5, sample size is: 5
+ sending known command
+ 2 total queries
+ preparing listkeys for "phases"
+ sending listkeys command
+ received listkey for "phases": 58 bytes
+ preparing listkeys for "namespaces"
+ sending listkeys command
+ received listkey for "namespaces": 40 bytes
OBSEXC: computing relevant nodes
OBSEXC: looking for common markers in 6 nodes
+ query 0; add more sample (target 100, current 1)
+ query 0; sample size is 9, largest range 5
+ sending evoext_obshashrange_v0 command
+ obsdiscovery, 0/5 mismatch - 1 obshashrange queries in *.???? seconds (glob)
OBSEXC: computing markers relevant to 1 nodes
+ checking for updated bookmarks
+ preparing listkeys for "bookmarks"
+ sending listkeys command
+ received listkey for "bookmarks": 0 bytes
+ 1 changesets found
+ list of changesets:
+ 45f8b879de922f6a6e620ba04205730335b6fc7e
+ sending unbundle command
+ bundle2-output-bundle: "HG20", 4 parts total
+ bundle2-output-part: "replycaps" 172 bytes payload
+ bundle2-output-part: "changegroup" (params: 1 mandatory) streamed payload
+ bundle2-output-part: "pushkey" (params: 4 mandatory) empty payload
+ bundle2-output-part: "obsmarkers" streamed payload
remote: adding changesets
remote: adding manifests
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files (+1 heads)
remote: 1 new obsolescence markers
+ bundle2-input-bundle: with-transaction
+ bundle2-input-part: "reply:changegroup" (advisory) (params: 0 advisory) supported
+ bundle2-input-part: "reply:pushkey" (params: 0 advisory) supported
+ bundle2-input-part: "reply:obsmarkers" (params: 0 advisory) supported
+ bundle2-input-bundle: 2 parts total
+ preparing listkeys for "phases"
+ sending listkeys command
+ received listkey for "phases": 58 bytes
+ $ hg -R ../server blackbox
+ * @0000000000000000000000000000000000000000 (*)> serve --stdio (glob)
+ * @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 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)
+ * @0000000000000000000000000000000000000000 (*)> 1 incoming changes - new heads: 45f8b879de92 (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> blackbox (glob)
+ $ rm ../server/.hg/blackbox.log
testing push with extra local markers
=====================================
@@ -145,6 +284,14 @@
no changes found
remote: 2 new obsolescence markers
[1]
+ $ hg -R ../server blackbox
+ * @0000000000000000000000000000000000000000 (*)> serve --stdio (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 2o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 2o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> blackbox (glob)
+ $ rm ../server/.hg/blackbox.log
$ hg -R ../server/ debugobsolete --rev ::tip | sort
111111111111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -152,6 +299,46 @@
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 01241442b3c2bf3211e593b549c655ea65b295e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ $ hg blackbox
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> up (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> up exited 0 after *.?? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> add foo (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> add foo exited 0 after *.?? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> commit -m foo (glob)
+ * @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-obshashrange in *.???? seconds (1r, 0o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> commit -m foo exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (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 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)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete 111111111111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete 111111111111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete 22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete 22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 2/6 mismatch - 1 obshashrange queries in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push exited True after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
$ hg debugobsolete | sort
111111111111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -190,6 +377,24 @@
3 new obsolescence markers
(run 'hg heads' to see heads, 'hg merge' to merge)
+ $ hg -R ../server blackbox
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete --rev ::tip (glob)
+ * @0000000000000000000000000000000000000000 (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R ../server/ debugobsolete --rev ::tip exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete aaaaaaa11111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R ../server debugobsolete aaaaaaa11111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete bbbbbbb2222222222bbbbbbbbbbbbb2222222222 bebd167eb94d257ace0e814aeb98e6972ed2970d (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R ../server debugobsolete bbbbbbb2222222222bbbbbbbbbbbbb2222222222 bebd167eb94d257ace0e814aeb98e6972ed2970d exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> serve --stdio (glob)
+ * @0000000000000000000000000000000000000000 (*)> -R server serve --stdio exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> blackbox (glob)
+ $ rm ../server/.hg/blackbox.log
$ hg -R ../server/ debugobsolete --rev '::6' | sort
111111111111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -199,6 +404,24 @@
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 01241442b3c2bf3211e593b549c655ea65b295e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
dddddddddddddddddddddddddddddddddddddddd c8d03c1b5e94af74b772900c58259d2e08917735 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+ $ hg blackbox
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r 6 (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 2/6 mismatch - 1 obshashrange queries in *.???? seconds (glob)
+ * @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 stablerange cache in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (2r, 3o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 3o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 2 incoming changes - new heads: f69452c5b1af (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r 6 exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
$ hg debugobsolete --rev '::6' | sort
111111111111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
@@ -209,3 +432,336 @@
cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
dddddddddddddddddddddddddddddddddddddddd c8d03c1b5e94af74b772900c58259d2e08917735 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'}
+Test cache behavior
+===================
+
+Adding markers affecting already used range:
+--------------------------------------------
+
+ $ hg debugobshashrange --subranges --rev 'heads(all())'
+ rev node index size depth obshash
+ 7 f69452c5b1af 0 7 7 000000000000
+ 5 45f8b879de92 0 6 6 1643971dbe2d
+ 3 2dc09a01254d 0 4 4 6be48f31976a
+ 7 f69452c5b1af 4 3 7 000000000000
+ 3 2dc09a01254d 2 2 4 9522069ae085
+ 5 45f8b879de92 4 2 6 9c26c72819c0
+ 1 66f7d451a68b 0 2 2 853c77a32154
+ 6 c8d03c1b5e94 4 2 6 ec8a3e92c525
+ 2 01241442b3c2 2 1 3 1ed3c61fb39a
+ 0 1ea73414a91b 0 1 1 000000000000
+ 3 2dc09a01254d 3 1 4 8a2acf8e1cde
+ 5 45f8b879de92 5 1 6 1a0c08180b65
+ 1 66f7d451a68b 1 1 2 853c77a32154
+ 4 bebd167eb94d 4 1 5 20a2cc572e4b
+ 6 c8d03c1b5e94 5 1 6 446c2dc3bce5
+ 7 f69452c5b1af 6 1 7 000000000000
+ $ hg -R ../server debugobsolete aaaa333333333aaaaa333a3a3a3a3a3a3a3a3a3a `getid 'desc(r1)'`
+ $ hg -R ../server debugobsolete bb4b4b4b4b4b4b4b44b4b4b4b4b4b4b4b4b4b4b4 `getid 'desc(r3)'`
+ $ hg pull -r `getid 'desc(r6)'`
+ pulling from ssh://user@dummy/server
+ no changes found
+ OBSEXC: looking for common markers in 7 nodes
+ OBSEXC: request obsmarkers for 2 common nodes
+ 2 new obsolescence markers
+ $ hg debugobshashrange --subranges --rev 'desc("r3")' -R ../server
+ rev node index size depth obshash
+ 3 2dc09a01254d 0 4 4 8932bf980bb4
+ 3 2dc09a01254d 2 2 4 ce1937ca1278
+ 1 66f7d451a68b 0 2 2 327c7dd73d29
+ 2 01241442b3c2 2 1 3 1ed3c61fb39a
+ 0 1ea73414a91b 0 1 1 000000000000
+ 3 2dc09a01254d 3 1 4 26f996446ecb
+ 1 66f7d451a68b 1 1 2 327c7dd73d29
+ $ hg debugobshashrange --subranges --rev 'desc("r3")'
+ rev node index size depth obshash
+ 3 2dc09a01254d 0 4 4 8932bf980bb4
+ 3 2dc09a01254d 2 2 4 ce1937ca1278
+ 1 66f7d451a68b 0 2 2 327c7dd73d29
+ 2 01241442b3c2 2 1 3 1ed3c61fb39a
+ 0 1ea73414a91b 0 1 1 000000000000
+ 3 2dc09a01254d 3 1 4 26f996446ecb
+ 1 66f7d451a68b 1 1 2 327c7dd73d29
+ $ hg blackbox
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete --rev ::6 (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete --rev ::6 exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r f69452c5b1af6cbaaa56ef50cf94fff5bcc6ca23 (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 2/7 mismatch - 1 obshashrange queries in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 2o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 2o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r f69452c5b1af6cbaaa56ef50cf94fff5bcc6ca23 exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev desc("r3") (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev desc("r3") exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
+
+Adding prune markers on existing changeset
+------------------------------------------
+
+ $ hg -R ../server debugobsolete --record-parents `getid 'desc(foo)'`
+ $ hg pull -r `getid 'desc(r4)'`
+ pulling from ssh://user@dummy/server
+ no changes found
+ OBSEXC: looking for common markers in 5 nodes
+ OBSEXC: request obsmarkers for 1 common nodes
+ 1 new obsolescence markers
+ $ hg blackbox
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r bebd167eb94d257ace0e814aeb98e6972ed2970d (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 1/5 mismatch - 1 obshashrange queries in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obshashrange in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r bebd167eb94d257ace0e814aeb98e6972ed2970d exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
+ $ hg debugobshashrange --subranges --rev 'heads(all())'
+ rev node index size depth obshash
+ 7 f69452c5b1af 0 7 7 000000000000
+ 5 45f8b879de92 0 6 6 b8a4206b0fc6
+ 3 2dc09a01254d 0 4 4 8932bf980bb4
+ 7 f69452c5b1af 4 3 7 000000000000
+ 3 2dc09a01254d 2 2 4 ce1937ca1278
+ 5 45f8b879de92 4 2 6 31fc49d36a59
+ 1 66f7d451a68b 0 2 2 327c7dd73d29
+ 6 c8d03c1b5e94 4 2 6 89755fd39e6d
+ 2 01241442b3c2 2 1 3 1ed3c61fb39a
+ 0 1ea73414a91b 0 1 1 000000000000
+ 3 2dc09a01254d 3 1 4 26f996446ecb
+ 5 45f8b879de92 5 1 6 1a0c08180b65
+ 1 66f7d451a68b 1 1 2 327c7dd73d29
+ 4 bebd167eb94d 4 1 5 b21465ecb790
+ 6 c8d03c1b5e94 5 1 6 446c2dc3bce5
+ 7 f69452c5b1af 6 1 7 000000000000
+
+Recover after rollback
+
+ $ hg pull
+ pulling from ssh://user@dummy/server
+ searching for changes
+ OBSEXC: looking for common markers in 8 nodes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 0 changes to 0 files
+ 1 new obsolescence markers
+ (run 'hg update' to get a working copy)
+ $ hg rollback
+ repository tip rolled back to revision 7 (undo pull)
+ $ hg blackbox
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obsdiscovery, 0/8 mismatch - 1 obshashrange queries in *.???? seconds (glob)
+ * @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 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)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 1 incoming changes - new heads: 4de32a90b66c (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> rollback (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated base branch cache in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> wrote base branch cache with 1 labels and 2 nodes (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> rollback exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
+ $ hg debugobshashrange --subranges --rev 'heads(all())'
+ rev node index size depth obshash
+ 7 f69452c5b1af 0 7 7 000000000000
+ 5 45f8b879de92 0 6 6 b8a4206b0fc6
+ 3 2dc09a01254d 0 4 4 8932bf980bb4
+ 7 f69452c5b1af 4 3 7 000000000000
+ 3 2dc09a01254d 2 2 4 ce1937ca1278
+ 5 45f8b879de92 4 2 6 31fc49d36a59
+ 1 66f7d451a68b 0 2 2 327c7dd73d29
+ 6 c8d03c1b5e94 4 2 6 89755fd39e6d
+ 2 01241442b3c2 2 1 3 1ed3c61fb39a
+ 0 1ea73414a91b 0 1 1 000000000000
+ 3 2dc09a01254d 3 1 4 26f996446ecb
+ 5 45f8b879de92 5 1 6 1a0c08180b65
+ 1 66f7d451a68b 1 1 2 327c7dd73d29
+ 4 bebd167eb94d 4 1 5 b21465ecb790
+ 6 c8d03c1b5e94 5 1 6 446c2dc3bce5
+ 7 f69452c5b1af 6 1 7 000000000000
+ $ hg pull
+ pulling from ssh://user@dummy/server
+ searching for changes
+ OBSEXC: looking for common markers in 8 nodes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 0 changes to 0 files
+ 1 new obsolescence markers
+ (run 'hg update' to get a working copy)
+ $ hg blackbox
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) (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)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull (glob)
+ * @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 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)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> 1 incoming changes - new heads: 4de32a90b66c (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
+ $ hg debugobshashrange --subranges --rev 'heads(all())'
+ rev node index size depth obshash
+ 8 4de32a90b66c 0 8 8 c7f1f7e9925b
+ 5 45f8b879de92 0 6 6 b8a4206b0fc6
+ 3 2dc09a01254d 0 4 4 8932bf980bb4
+ 8 4de32a90b66c 4 4 8 c681c3e58c27
+ 3 2dc09a01254d 2 2 4 ce1937ca1278
+ 5 45f8b879de92 4 2 6 31fc49d36a59
+ 8 4de32a90b66c 6 2 8 033544c939f0
+ 1 66f7d451a68b 0 2 2 327c7dd73d29
+ 6 c8d03c1b5e94 4 2 6 89755fd39e6d
+ 2 01241442b3c2 2 1 3 1ed3c61fb39a
+ 0 1ea73414a91b 0 1 1 000000000000
+ 3 2dc09a01254d 3 1 4 26f996446ecb
+ 5 45f8b879de92 5 1 6 1a0c08180b65
+ 8 4de32a90b66c 7 1 8 033544c939f0
+ 1 66f7d451a68b 1 1 2 327c7dd73d29
+ 4 bebd167eb94d 4 1 5 b21465ecb790
+ 6 c8d03c1b5e94 5 1 6 446c2dc3bce5
+ 7 f69452c5b1af 6 1 7 000000000000
+
+Recover after stripping (in the middle of the repo)
+
+We strip a branch that is not the tip of the reporiosy so part of the affected
+revision are reapplied after the target is stripped.
+
+ $ hg log -G
+ o 8 4de32a90b66c r7 tip
+ |
+ o 7 f69452c5b1af r6
+ |
+ o 6 c8d03c1b5e94 r5
+ |
+ | @ 5 45f8b879de92 foo
+ |/
+ o 4 bebd167eb94d r4
+ |
+ o 3 2dc09a01254d r3
+ |
+ o 2 01241442b3c2 r2
+ |
+ o 1 66f7d451a68b r1
+ |
+ o 0 1ea73414a91b r0
+
+ $ hg --config extensions.strip= strip -r 'desc("foo")'
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ saved backup bundle to $TESTTMP/client/.hg/strip-backup/45f8b879de92-94c82517-backup.hg (glob)
+ $ hg log -G
+ o 7 4de32a90b66c r7 tip
+ |
+ o 6 f69452c5b1af r6
+ |
+ o 5 c8d03c1b5e94 r5
+ |
+ @ 4 bebd167eb94d r4
+ |
+ o 3 2dc09a01254d r3
+ |
+ o 2 01241442b3c2 r2
+ |
+ o 1 66f7d451a68b r1
+ |
+ o 0 1ea73414a91b r0
+
+ $ hg pull
+ pulling from ssh://user@dummy/server
+ searching for changes
+ OBSEXC: looking for common markers in 8 nodes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files (+1 heads)
+ (run 'hg heads' to see heads, 'hg merge' to merge)
+ $ hg log -G
+ o 8 45f8b879de92 foo tip
+ |
+ | o 7 4de32a90b66c r7
+ | |
+ | o 6 f69452c5b1af r6
+ | |
+ | o 5 c8d03c1b5e94 r5
+ |/
+ @ 4 bebd167eb94d r4
+ |
+ o 3 2dc09a01254d r3
+ |
+ o 2 01241442b3c2 r2
+ |
+ o 1 66f7d451a68b r1
+ |
+ o 0 1ea73414a91b r0
+
+ $ hg blackbox
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobshashrange --subranges --rev heads(all()) exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G exited 0 after *.?? seconds (glob)
+ * @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 (*)> 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 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)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated base branch cache in *.???? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote base branch cache with 1 labels and 1 nodes (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> 3 incoming changes - new heads: 4de32a90b66c (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> --config extensions.strip= strip -r desc("foo") exited 0 after *.?? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> log -G (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> log -G exited 0 after *.?? seconds (glob)
+ * @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 stablerange cache in *.???? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated evo-ext-obshashrange in *.???? seconds (1r, 0o) (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> updated served branch cache in *.???? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> wrote served branch cache with 1 labels and 2 nodes (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> 1 incoming changes - new heads: 45f8b879de92 (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> pull exited 0 after *.?? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> log -G (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> writing .hg/cache/tags2-visible with 0 tags (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> log -G exited 0 after *.?? seconds (glob)
+ * @bebd167eb94d257ace0e814aeb98e6972ed2970d (*)> blackbox (glob)
+ $ rm .hg/blackbox.log
+ $ hg debugobshashrange --subranges --rev 'heads(all())'
+ rev node index size depth obshash
+ 7 4de32a90b66c 0 8 8 c7f1f7e9925b
+ 8 45f8b879de92 0 6 6 b8a4206b0fc6
+ 3 2dc09a01254d 0 4 4 8932bf980bb4
+ 7 4de32a90b66c 4 4 8 c681c3e58c27
+ 3 2dc09a01254d 2 2 4 ce1937ca1278
+ 8 45f8b879de92 4 2 6 31fc49d36a59
+ 7 4de32a90b66c 6 2 8 033544c939f0
+ 1 66f7d451a68b 0 2 2 327c7dd73d29
+ 5 c8d03c1b5e94 4 2 6 89755fd39e6d
+ 2 01241442b3c2 2 1 3 1ed3c61fb39a
+ 0 1ea73414a91b 0 1 1 000000000000
+ 3 2dc09a01254d 3 1 4 26f996446ecb
+ 8 45f8b879de92 5 1 6 1a0c08180b65
+ 7 4de32a90b66c 7 1 8 033544c939f0
+ 1 66f7d451a68b 1 1 2 327c7dd73d29
+ 4 bebd167eb94d 4 1 5 b21465ecb790
+ 5 c8d03c1b5e94 5 1 6 446c2dc3bce5
+ 6 f69452c5b1af 6 1 7 000000000000
+
--- a/tests/test-evolve-obshistory.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,514 +0,0 @@
-This test file test the various messages when accessing obsolete
-revisions.
-
-Global setup
-============
-
- $ . $TESTDIR/testlib/common.sh
- $ cat >> $HGRCPATH <<EOF
- > [ui]
- > interactive = true
- > [phases]
- > publish=False
- > [extensions]
- > evolve =
- > EOF
-
-Test output on amended commit
-=============================
-
-Test setup
-----------
-
- $ hg init $TESTTMP/local-amend
- $ cd $TESTTMP/local-amend
- $ mkcommit ROOT
- $ mkcommit A0
- $ echo 42 >> A0
- $ hg amend -m "A1"
- $ hg log --hidden -G
- @ changeset: 3:a468dc9b3633
- | tag: tip
- | parent: 0:ea207398892e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A1
- |
- | x changeset: 2:f137d23bb3e1
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: temporary amend commit for 471f378eab4c
- | |
- | x changeset: 1:471f378eab4c
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
-Actual test
------------
-
- $ hg update 471f378eab4c
- abort: hidden revision '471f378eab4c'!
- (use --hidden to access hidden revisions)
- [255]
- $ hg update --hidden "desc(A0)"
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory parent is obsolete! (471f378eab4c)
- (use 'hg evolve' to update to its successor: a468dc9b3633)
-
-Test output with pruned commit
-==============================
-
-Test setup
-----------
-
- $ hg init $TESTTMP/local-prune
- $ cd $TESTTMP/local-prune
- $ mkcommit ROOT
- $ mkcommit A0 # 0
- $ mkcommit B0 # 1
- $ hg log --hidden -G
- @ changeset: 2:0dec01379d3b
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: B0
- |
- o changeset: 1:471f378eab4c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
- $ hg prune -r 'desc(B0)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- working directory now at 471f378eab4c
- 1 changesets pruned
-
-Actual test
------------
-
- $ hg up 1
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg up 0dec01379d3b
- abort: hidden revision '0dec01379d3b'!
- (use --hidden to access hidden revisions)
- [255]
- $ hg up --hidden -r 'desc(B0)'
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory parent is obsolete! (0dec01379d3b)
- (use 'hg evolve' to update to its parent successor)
-
-Test output with splitted commit
-================================
-
-Test setup
-----------
-
- $ hg init $TESTTMP/local-split
- $ cd $TESTTMP/local-split
- $ mkcommit ROOT
- $ echo 42 >> a
- $ echo 43 >> b
- $ hg commit -A -m "A0"
- adding a
- adding b
- $ hg log --hidden -G
- @ changeset: 1:471597cad322
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
- $ hg split -r 'desc(A0)' -d "0 0" << EOF
- > y
- > y
- > n
- > n
- > y
- > y
- > EOF
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- adding a
- adding b
- diff --git a/a b/a
- new file mode 100644
- examine changes to 'a'? [Ynesfdaq?] y
-
- @@ -0,0 +1,1 @@
- +42
- record change 1/2 to 'a'? [Ynesfdaq?] y
-
- diff --git a/b b/b
- new file mode 100644
- examine changes to 'b'? [Ynesfdaq?] n
-
- created new head
- Done splitting? [yN] n
- diff --git a/b b/b
- new file mode 100644
- examine changes to 'b'? [Ynesfdaq?] y
-
- @@ -0,0 +1,1 @@
- +43
- record this change to 'b'? [Ynesfdaq?] y
-
- no more change to split
-
- $ hg log --hidden -G
- @ changeset: 3:f257fde29c7a
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 2:337fec4d2edc
- | parent: 0:ea207398892e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- | x changeset: 1:471597cad322
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
-Actual test
------------
-
- $ hg update 471597cad322
- abort: hidden revision '471597cad322'!
- (use --hidden to access hidden revisions)
- [255]
- $ hg update --hidden 'min(desc(A0))'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory parent is obsolete! (471597cad322)
- (use 'hg evolve' to update to its tipmost successor: 337fec4d2edc, f257fde29c7a)
-
-Test output with lots of splitted commit
-========================================
-
-Test setup
-----------
-
- $ hg init $TESTTMP/local-lots-split
- $ cd $TESTTMP/local-lots-split
- $ mkcommit ROOT
- $ echo 42 >> a
- $ echo 43 >> b
- $ echo 44 >> c
- $ echo 45 >> d
- $ hg commit -A -m "A0"
- adding a
- adding b
- adding c
- adding d
- $ hg log --hidden -G
- @ changeset: 1:de7290d8b885
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
-
- $ hg split -r 'desc(A0)' -d "0 0" << EOF
- > y
- > y
- > n
- > n
- > n
- > n
- > y
- > y
- > n
- > n
- > n
- > y
- > y
- > n
- > n
- > y
- > y
- > EOF
- 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
- adding a
- adding b
- adding c
- adding d
- diff --git a/a b/a
- new file mode 100644
- examine changes to 'a'? [Ynesfdaq?] y
-
- @@ -0,0 +1,1 @@
- +42
- record change 1/4 to 'a'? [Ynesfdaq?] y
-
- diff --git a/b b/b
- new file mode 100644
- examine changes to 'b'? [Ynesfdaq?] n
-
- diff --git a/c b/c
- new file mode 100644
- examine changes to 'c'? [Ynesfdaq?] n
-
- diff --git a/d b/d
- new file mode 100644
- examine changes to 'd'? [Ynesfdaq?] n
-
- created new head
- Done splitting? [yN] n
- diff --git a/b b/b
- new file mode 100644
- examine changes to 'b'? [Ynesfdaq?] y
-
- @@ -0,0 +1,1 @@
- +43
- record change 1/3 to 'b'? [Ynesfdaq?] y
-
- diff --git a/c b/c
- new file mode 100644
- examine changes to 'c'? [Ynesfdaq?] n
-
- diff --git a/d b/d
- new file mode 100644
- examine changes to 'd'? [Ynesfdaq?] n
-
- Done splitting? [yN] n
- diff --git a/c b/c
- new file mode 100644
- examine changes to 'c'? [Ynesfdaq?] y
-
- @@ -0,0 +1,1 @@
- +44
- 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] n
- diff --git a/d b/d
- new file mode 100644
- examine changes to 'd'? [Ynesfdaq?] y
-
- @@ -0,0 +1,1 @@
- +45
- record this change to 'd'? [Ynesfdaq?] y
-
- no more change to split
-
- $ hg log --hidden -G
- @ changeset: 5:c7f044602e9b
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 4:1ae8bc733a14
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 3:f257fde29c7a
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 2:337fec4d2edc
- | parent: 0:ea207398892e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- | x changeset: 1:de7290d8b885
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
-Actual test
------------
-
- $ hg update de7290d8b885
- abort: hidden revision 'de7290d8b885'!
- (use --hidden to access hidden revisions)
- [255]
- $ hg update --hidden 'min(desc(A0))'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory parent is obsolete! (de7290d8b885)
- (use 'hg evolve' to update to its tipmost successor: 337fec4d2edc, f257fde29c7a and 2 more)
-
-Test output with folded commit
-==============================
-
-Test setup
-----------
-
- $ hg init $TESTTMP/local-fold
- $ cd $TESTTMP/local-fold
- $ mkcommit ROOT
- $ mkcommit A0
- $ mkcommit B0
- $ hg log --hidden -G
- @ changeset: 2:0dec01379d3b
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: B0
- |
- o changeset: 1:471f378eab4c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
- $ hg fold --exact -r 'desc(A0) + desc(B0)' --date "0 0" -m "C0"
- 2 changesets folded
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg log --hidden -G
- @ changeset: 3:eb5a0daa2192
- | tag: tip
- | parent: 0:ea207398892e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: C0
- |
- | x changeset: 2:0dec01379d3b
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: B0
- | |
- | x changeset: 1:471f378eab4c
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
- Actual test
- -----------
-
- $ hg update 471f378eab4c
- abort: hidden revision '471f378eab4c'!
- (use --hidden to access hidden revisions)
- [255]
- $ hg update --hidden 'desc(A0)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- working directory parent is obsolete! (471f378eab4c)
- (use 'hg evolve' to update to its successor: eb5a0daa2192)
- $ hg update 0dec01379d3b
- working directory parent is obsolete! (471f378eab4c)
- (use 'hg evolve' to update to its successor: eb5a0daa2192)
- abort: hidden revision '0dec01379d3b'!
- (use --hidden to access hidden revisions)
- [255]
- $ hg update --hidden 'desc(B0)'
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory parent is obsolete! (0dec01379d3b)
- (use 'hg evolve' to update to its successor: eb5a0daa2192)
-
-Test output with divergence
-===========================
-
-Test setup
-----------
-
- $ hg init $TESTTMP/local-divergence
- $ cd $TESTTMP/local-divergence
- $ mkcommit ROOT
- $ mkcommit A0
- $ hg amend -m "A1"
- $ hg log --hidden -G
- @ changeset: 2:fdf9bde5129a
- | tag: tip
- | parent: 0:ea207398892e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A1
- |
- | x changeset: 1:471f378eab4c
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
- $ hg update --hidden 'desc(A0)'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory parent is obsolete! (471f378eab4c)
- (use 'hg evolve' to update to its successor: fdf9bde5129a)
- $ hg amend -m "A2"
- 2 new divergent changesets
- $ hg log --hidden -G
- @ changeset: 3:65b757b745b9
- | tag: tip
- | parent: 0:ea207398892e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A2
- |
- | o changeset: 2:fdf9bde5129a
- |/ parent: 0:ea207398892e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A1
- |
- | x changeset: 1:471f378eab4c
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: A0
- |
- o changeset: 0:ea207398892e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: ROOT
-
-Actual test
------------
-
- $ hg update 471f378eab4c
- abort: hidden revision '471f378eab4c'!
- (use --hidden to access hidden revisions)
- [255]
- $ hg update --hidden 'desc(A0)'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- working directory parent is obsolete! (471f378eab4c)
- (471f378eab4c has diverged, use 'hg evolve -list --divergent' to resolve the issue)
--- a/tests/test-evolve-topic.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,217 +0,0 @@
-
-Check we can find the topic extensions
-
- $ cat >> $HGRCPATH <<EOF
- > [defaults]
- > amend=-d "0 0"
- > fold=-d "0 0"
- > [phases]
- > publish = False
- > [ui]
- > logtemplate = {rev} - \{{get(namespaces, "topics")}} {node|short} {desc} ({phase})\n
- > [diff]
- > git = 1
- > unified = 0
- > [extensions]
- > rebase =
- > EOF
- $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
- $ echo "topic=$(echo $(dirname $TESTDIR))/hgext3rd/topic/" >> $HGRCPATH
-
- $ mkcommit() {
- > echo "$1" > "$1"
- > hg add "$1"
- > hg ci -m "add $1"
- > }
-
-Create a simple setup
-
- $ hg init repoa
- $ cd repoa
- $ mkcommit aaa
- $ mkcommit bbb
- $ hg topic foo
- $ mkcommit ccc
- $ mkcommit ddd
- $ mkcommit eee
- $ mkcommit fff
- $ hg topic bar
- $ mkcommit ggg
- $ mkcommit hhh
- $ mkcommit iii
- $ mkcommit jjj
-
- $ hg log -G
- @ 9 - {bar} 1d964213b023 add jjj (draft)
- |
- o 8 - {bar} fcab990f3261 add iii (draft)
- |
- o 7 - {bar} b0c2554835ac add hhh (draft)
- |
- o 6 - {bar} c748293f1c1a add ggg (draft)
- |
- o 5 - {foo} 6a6b7365c751 add fff (draft)
- |
- o 4 - {foo} 3969ab847d9c add eee (draft)
- |
- o 3 - {foo} 4e3a154f38c7 add ddd (draft)
- |
- o 2 - {foo} cced9bac76e3 add ccc (draft)
- |
- o 1 - {} a4dbed0837ea add bbb (draft)
- |
- o 0 - {} 199cc73e9a0b add aaa (draft)
-
-
-Test that evolve --all evolve the current topic
------------------------------------------------
-
-make a mess
-
- $ hg up foo
- switching to topic foo
- 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
- $ hg topic -l
- ### topic: foo (?)
- ### branch: default (?)
- t4@ add fff (current)
- t3: add eee
- t2: add ddd
- t1: add ccc
- ^ add bbb
- $ hg up 'desc(ddd)'
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ echo ddd >> ddd
- $ hg amend
- 6 new unstable changesets
- $ hg up 'desc(fff)'
- 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ echo fff >> fff
- $ hg amend
-
- $ hg log -G
- @ 13 - {foo} e104f49bab28 add fff (draft)
- |
- | o 11 - {foo} d9cacd156ffc add ddd (draft)
- | |
- | | o 9 - {bar} 1d964213b023 add jjj (draft)
- | | |
- | | o 8 - {bar} fcab990f3261 add iii (draft)
- | | |
- | | o 7 - {bar} b0c2554835ac add hhh (draft)
- | | |
- | | o 6 - {bar} c748293f1c1a add ggg (draft)
- | | |
- +---x 5 - {foo} 6a6b7365c751 add fff (draft)
- | |
- o | 4 - {foo} 3969ab847d9c add eee (draft)
- | |
- x | 3 - {foo} 4e3a154f38c7 add ddd (draft)
- |/
- o 2 - {foo} cced9bac76e3 add ccc (draft)
- |
- o 1 - {} a4dbed0837ea add bbb (draft)
- |
- o 0 - {} 199cc73e9a0b add aaa (draft)
-
-
-Run evolve --all
-
- $ hg evolve --all
- move:[4] add eee
- atop:[11] add ddd
- move:[13] add fff
- atop:[14] add eee
- working directory is now at 070c5573d8f9
- $ hg log -G
- @ 15 - {foo} 070c5573d8f9 add fff (draft)
- |
- o 14 - {foo} 42b49017ff90 add eee (draft)
- |
- o 11 - {foo} d9cacd156ffc add ddd (draft)
- |
- | o 9 - {bar} 1d964213b023 add jjj (draft)
- | |
- | o 8 - {bar} fcab990f3261 add iii (draft)
- | |
- | o 7 - {bar} b0c2554835ac add hhh (draft)
- | |
- | o 6 - {bar} c748293f1c1a add ggg (draft)
- | |
- | x 5 - {foo} 6a6b7365c751 add fff (draft)
- | |
- | x 4 - {foo} 3969ab847d9c add eee (draft)
- | |
- | x 3 - {foo} 4e3a154f38c7 add ddd (draft)
- |/
- o 2 - {foo} cced9bac76e3 add ccc (draft)
- |
- o 1 - {} a4dbed0837ea add bbb (draft)
- |
- o 0 - {} 199cc73e9a0b add aaa (draft)
-
-
-Test that evolve does not loose topic information
--------------------------------------------------
-
- $ hg evolve --rev 'topic(bar)'
- move:[6] add ggg
- atop:[15] add fff
- move:[7] add hhh
- atop:[16] add ggg
- move:[8] add iii
- atop:[17] add hhh
- move:[9] add jjj
- atop:[18] add iii
- working directory is now at 9bf430c106b7
- $ hg log -G
- @ 19 - {bar} 9bf430c106b7 add jjj (draft)
- |
- o 18 - {bar} d2dc89c57700 add iii (draft)
- |
- o 17 - {bar} 20bc4d02aa62 add hhh (draft)
- |
- o 16 - {bar} 16d6f664b17c add ggg (draft)
- |
- o 15 - {foo} 070c5573d8f9 add fff (draft)
- |
- o 14 - {foo} 42b49017ff90 add eee (draft)
- |
- o 11 - {foo} d9cacd156ffc add ddd (draft)
- |
- o 2 - {foo} cced9bac76e3 add ccc (draft)
- |
- o 1 - {} a4dbed0837ea add bbb (draft)
- |
- o 0 - {} 199cc73e9a0b add aaa (draft)
-
-
-Tests next and prev behavior
-============================
-
-Basic move are restricted to the current topic
-
- $ hg up foo
- switching to topic foo
- 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
- $ hg prev
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- [14] add eee
- $ hg next
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- [15] add fff
- $ hg next
- no children on topic "foo"
- do you want --no-topic
- [1]
- $ hg next --no-topic
- switching to topic bar
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- [16] add ggg
- $ hg prev
- no parent in topic "bar"
- (do you want --no-topic)
- $ hg prev --no-topic
- switching to topic foo
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- [15] add fff
--- a/tests/test-evolve.t Wed May 03 13:23:36 2017 +0200
+++ b/tests/test-evolve.t Thu May 18 23:51:10 2017 +0200
@@ -767,12 +767,6 @@
$ hg debugrebuildstate
$ hg st
-Test olog
-
- $ hg olog
- 4 : add 4 - test
- 11 : add 3 - test
-
Test obsstore stat
$ hg debugobsstorestat
--- a/tests/test-obsolete.t Wed May 03 13:23:36 2017 +0200
+++ b/tests/test-obsolete.t Thu May 18 23:51:10 2017 +0200
@@ -1,3 +1,5 @@
+
+ $ . $TESTDIR/testlib/common.sh
$ cat >> $HGRCPATH <<EOF
> [web]
> push_ssl = false
@@ -8,6 +10,7 @@
> debugobsolete=debugobsolete -d '0 0'
> [extensions]
> hgext.rebase=
+ > color =
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
$ mkcommit() {
@@ -15,10 +18,6 @@
> hg add "$1"
> hg ci -m "add $1"
> }
- $ getid() {
- > hg id --hidden --debug -ir "$1"
- > }
-
$ alias qlog="hg log --template='{rev}\n- {node|short}\n'"
$ hg init local
$ cd local
@@ -689,12 +688,6 @@
[4] add obsol_c'
[10] add obsol_c
[2]
- $ hg olog
- changeset: 2:4538525df7e2
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: add c
-
Check import reports new unstable changeset:
--- a/tests/test-prev-next.t Wed May 03 13:23:36 2017 +0200
+++ b/tests/test-prev-next.t Thu May 18 23:51:10 2017 +0200
@@ -1,6 +1,7 @@
$ cat >> $HGRCPATH <<EOF
> [extensions]
> hgext.graphlog=
+ > color =
> EOF
$ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH
@@ -47,6 +48,9 @@
$ hg bookmarks
mark 1:6e742c9127b3
* mark2 0:a154386e50d1
+ $ hg next --dry-run --color=debug
+ hg update 1;
+ [[evolve.rev|1]] added b
$ hg next
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
[1] added b
@@ -147,6 +151,9 @@
$ hg next --evolve
no children
[1]
+ $ hg prev --dry-run --color=debug
+ hg update 1;
+ [[evolve.rev|1]] added b
$ hg prev
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
[1] added b
--- a/tests/test-topic-dest.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,492 +0,0 @@
- $ . "$TESTDIR/testlib/topic_setup.sh"
-
- $ hg init jungle
- $ cd jungle
- $ cat <<EOF >> .hg/hgrc
- > [extensions]
- > rebase=
- > histedit=
- > [phases]
- > publish=false
- > EOF
- $ cat <<EOF >> $HGRCPATH
- > [ui]
- > logtemplate = '{rev} ({topics}) {desc}\n'
- > EOF
-
- $ for x in alpha beta gamma delta ; do
- > echo file $x >> $x
- > hg add $x
- > hg ci -m "c_$x"
- > done
-
-Test NGTip feature
-==================
-
-Simple linear case
-
- $ echo babar >> jungle
- $ hg add jungle
- $ hg ci -t elephant -m babar
-
- $ hg log -G
- @ 4 (elephant) babar
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
- $ hg log -r 'ngtip(.)'
- 3 () c_delta
- $ hg log -r 'default'
- 3 () c_delta
-
-
-multiple heads with topic
-
- $ hg up "desc('c_beta')"
- 0 files updated, 0 files merged, 3 files removed, 0 files unresolved
- $ echo zephir >> jungle
- $ hg add jungle
- $ hg ci -t monkey -m zephir
- $ hg log -G
- @ 5 (monkey) zephir
- |
- | o 4 (elephant) babar
- | |
- | o 3 () c_delta
- | |
- | o 2 () c_gamma
- |/
- o 1 () c_beta
- |
- o 0 () c_alpha
-
- $ hg log -r 'ngtip(.)'
- 3 () c_delta
- $ hg log -r 'default'
- 3 () c_delta
-
-one of the head is a valid tip
-
- $ hg up "desc('c_delta')"
- 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ echo epsilon >> epsilon
- $ hg add epsilon
- $ hg ci -m "c_epsilon"
- $ hg log -G
- @ 6 () c_epsilon
- |
- | o 5 (monkey) zephir
- | |
- +---o 4 (elephant) babar
- | |
- o | 3 () c_delta
- | |
- o | 2 () c_gamma
- |/
- o 1 () c_beta
- |
- o 0 () c_alpha
-
- $ hg log -r 'ngtip(.)'
- 6 () c_epsilon
- $ hg log -r 'default'
- 6 () c_epsilon
-
-rebase destination
-==================
-
-rebase on branch ngtip
-
- $ hg up elephant
- switching to topic elephant
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg rebase
- rebasing 4:cb7ae72f4a80 "babar"
- $ hg log -G
- @ 7 (elephant) babar
- |
- o 6 () c_epsilon
- |
- | o 5 (monkey) zephir
- | |
- o | 3 () c_delta
- | |
- o | 2 () c_gamma
- |/
- o 1 () c_beta
- |
- o 0 () c_alpha
-
- $ hg up monkey
- switching to topic monkey
- 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
- $ hg rebase
- rebasing 5:d832ddc604ec "zephir"
- $ hg log -G
- @ 8 (monkey) zephir
- |
- | o 7 (elephant) babar
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
-
-Rebase on other topic heads if any
-
- $ hg up 'desc(c_delta)'
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ echo "General Huc" >> monkeyville
- $ hg add monkeyville
- $ hg ci -t monkey -m Huc
- $ hg log -G
- @ 9 (monkey) Huc
- |
- | o 8 (monkey) zephir
- | |
- | | o 7 (elephant) babar
- | |/
- | o 6 () c_epsilon
- |/
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
- $ hg rebase
- rebasing 9:d79a104e2902 "Huc" (tip)
- $ hg log -G
- @ 10 (monkey) Huc
- |
- o 8 (monkey) zephir
- |
- | o 7 (elephant) babar
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
-
-merge destination
-=================
-
- $ hg up 'ngtip(default)'
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ hg up default
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ echo zeta >> zeta
- $ hg add zeta
- $ hg ci -m "c_zeta"
- $ hg log -G
- @ 11 () c_zeta
- |
- | o 10 (monkey) Huc
- | |
- | o 8 (monkey) zephir
- |/
- | o 7 (elephant) babar
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
- $ hg up elephant
- switching to topic elephant
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg rebase -d 'desc(c_zeta)' # make sure tip is elsewhere
- rebasing 7:8d0b77140b05 "babar"
- $ hg up monkey
- switching to topic monkey
- 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg merge
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- (branch merge, don't forget to commit)
- $ hg topic
- elephant
- * monkey
- $ hg ci -m 'merge with default'
- $ hg topic
- elephant
- * monkey
- $ hg log -G
- @ 13 (monkey) merge with default
- |\
- | | o 12 (elephant) babar
- | |/
- | o 11 () c_zeta
- | |
- o | 10 (monkey) Huc
- | |
- o | 8 (monkey) zephir
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
-
-
-Check pull --rebase
--------------------
-
-(we broke it a some point)
-
- $ cd ..
- $ hg clone jungle other --rev '2'
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 3 changes to 3 files
- updating to branch default
- 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ cd other
- $ echo other > other
- $ hg add other
- $ hg ci -m 'c_other'
- $ hg pull -r default --rebase
- pulling from $TESTTMP/jungle (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 3 changes to 3 files (+1 heads)
- rebasing 3:dbc48dd9e743 "c_other"
- $ hg log -G
- @ 7 () c_other
- |
- o 6 () c_zeta
- |
- o 5 () c_epsilon
- |
- o 4 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
- $ cd ../jungle
-
-
-Default destination for update
-===============================
-
-initial setup
-
- $ hg up elephant
- switching to topic elephant
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ echo arthur >> jungle
- $ hg ci -m arthur
- $ echo pompadour >> jungle
- $ hg ci -m pompadour
- $ hg up 'roots(all())'
- 0 files updated, 0 files merged, 6 files removed, 0 files unresolved
- $ hg log -G
- o 15 (elephant) pompadour
- |
- o 14 (elephant) arthur
- |
- | o 13 (monkey) merge with default
- | |\
- o---+ 12 (elephant) babar
- / /
- | o 11 () c_zeta
- | |
- o | 10 (monkey) Huc
- | |
- o | 8 (monkey) zephir
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- @ 0 () c_alpha
-
-
-testing default destination on a branch
-
- $ hg up
- 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg log -G
- o 15 (elephant) pompadour
- |
- o 14 (elephant) arthur
- |
- | o 13 (monkey) merge with default
- | |\
- o---+ 12 (elephant) babar
- / /
- | @ 11 () c_zeta
- | |
- o | 10 (monkey) Huc
- | |
- o | 8 (monkey) zephir
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
-
-extra setup for topic
-(making sure tip is not the topic)
-
- $ hg up 'desc(c_zeta)'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ echo 'eta' >> 'eta'
- $ hg add 'eta'
- $ hg commit -m 'c_eta'
- $ hg log -G
- @ 16 () c_eta
- |
- | o 15 (elephant) pompadour
- | |
- | o 14 (elephant) arthur
- | |
- +---o 13 (monkey) merge with default
- | | |
- | o | 12 (elephant) babar
- |/ /
- o | 11 () c_zeta
- | |
- | o 10 (monkey) Huc
- | |
- | o 8 (monkey) zephir
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
-
-Testing default destination for topic
-
- $ hg up 'roots(topic(elephant))'
- switching to topic elephant
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg up
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg log -G
- o 16 () c_eta
- |
- | @ 15 (elephant) pompadour
- | |
- | o 14 (elephant) arthur
- | |
- +---o 13 (monkey) merge with default
- | | |
- | o | 12 (elephant) babar
- |/ /
- o | 11 () c_zeta
- | |
- | o 10 (monkey) Huc
- | |
- | o 8 (monkey) zephir
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
-
-Testing default destination for topic
-
- $ hg up 'p1(roots(topic(elephant)))'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg topic elephant
- $ hg up
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg log -G
- o 16 () c_eta
- |
- | @ 15 (elephant) pompadour
- | |
- | o 14 (elephant) arthur
- | |
- +---o 13 (monkey) merge with default
- | | |
- | o | 12 (elephant) babar
- |/ /
- o | 11 () c_zeta
- | |
- | o 10 (monkey) Huc
- | |
- | o 8 (monkey) zephir
- |/
- o 6 () c_epsilon
- |
- o 3 () c_delta
- |
- o 2 () c_gamma
- |
- o 1 () c_beta
- |
- o 0 () c_alpha
-
-
-Default destination for histedit
-================================
-
-By default histedit should edit with the current topic only
-(even when based on other draft
-
- $ hg phase 'desc(c_zeta)'
- 11: draft
- $ HGEDITOR=cat hg histedit | grep pick
- pick e44744d9ad73 12 babar
- pick 38eea8439aee 14 arthur
- pick 411315c48bdc 15 pompadour
- # p, pick = use commit
--- a/tests/test-topic-push.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,414 +0,0 @@
- $ . "$TESTDIR/testlib/topic_setup.sh"
-
- $ cat << EOF >> $HGRCPATH
- > [ui]
- > logtemplate = {rev} {branch} {get(namespaces, "topics")} {phase} {desc|firstline}\n
- > [ui]
- > ssh =python "$RUNTESTDIR/dummyssh"
- > EOF
-
- $ hg init main
- $ hg init draft
- $ cat << EOF >> draft/.hg/hgrc
- > [phases]
- > publish=False
- > EOF
- $ hg clone main client
- updating to branch default
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ cat << EOF >> client/.hg/hgrc
- > [paths]
- > draft=../draft
- > EOF
-
-
-Testing core behavior to make sure we did not break anything
-============================================================
-
-Pushing a first changeset
-
- $ cd client
- $ echo aaa > aaa
- $ hg add aaa
- $ hg commit -m 'CA'
- $ hg outgoing -G
- comparing with $TESTTMP/main (glob)
- searching for changes
- @ 0 default draft CA
-
- $ hg push
- pushing to $TESTTMP/main (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files
-
-Pushing two heads
-
- $ echo aaa > bbb
- $ hg add bbb
- $ hg commit -m 'CB'
- $ echo aaa > ccc
- $ hg up 'desc(CA)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg add ccc
- $ hg commit -m 'CC'
- created new head
- $ hg outgoing -G
- comparing with $TESTTMP/main (glob)
- searching for changes
- @ 2 default draft CC
-
- o 1 default draft CB
-
- $ hg push
- pushing to $TESTTMP/main (glob)
- searching for changes
- abort: push creates new remote head 9fe81b7f425d!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
- $ hg outgoing -r 'desc(CB)' -G
- comparing with $TESTTMP/main (glob)
- searching for changes
- o 1 default draft CB
-
- $ hg push -r 'desc(CB)'
- pushing to $TESTTMP/main (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files
-
-Pushing a new branch
-
- $ hg branch mountain
- marked working directory as branch mountain
- (branches are permanent and global, did you want a bookmark?)
- $ hg commit --amend
- $ hg outgoing -G
- comparing with $TESTTMP/main (glob)
- searching for changes
- @ 4 mountain draft CC
-
- $ hg push
- pushing to $TESTTMP/main (glob)
- searching for changes
- abort: push creates new remote branches: mountain!
- (use 'hg push --new-branch' to create new remote branches)
- [255]
- $ hg push --new-branch
- pushing to $TESTTMP/main (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files (+1 heads)
- 2 new obsolescence markers
-
-Including on non-publishing
-
- $ hg push --new-branch draft
- pushing to $TESTTMP/draft (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 3 changes to 3 files (+1 heads)
- 2 new obsolescence markers
-
-Testing topic behavior
-======================
-
-Local peer tests
-----------------
-
- $ hg up -r 'desc(CA)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg topic babar
- $ echo aaa > ddd
- $ hg add ddd
- $ hg commit -m 'CD'
- $ hg log -G # keep track of phase because I saw some strange bug during developement
- @ 5 default babar draft CD
- |
- | o 4 mountain public CC
- |/
- | o 1 default public CB
- |/
- o 0 default public CA
-
-
-Pushing a new topic to a non publishing server should not be seen as a new head
-
- $ hg push draft
- pushing to $TESTTMP/draft (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files (+1 heads)
- $ hg log -G
- @ 5 default babar draft CD
- |
- | o 4 mountain public CC
- |/
- | o 1 default public CB
- |/
- o 0 default public CA
-
-
-Pushing a new topic to a publishing server should be seen as a new head
-
- $ hg push
- pushing to $TESTTMP/main (glob)
- searching for changes
- abort: push creates new remote head 67f579af159d!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
- $ hg log -G
- @ 5 default babar draft CD
- |
- | o 4 mountain public CC
- |/
- | o 1 default public CB
- |/
- o 0 default public CA
-
-
-wireprotocol tests
-------------------
-
- $ hg up -r 'desc(CA)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg topic celeste
- $ echo aaa > eee
- $ hg add eee
- $ hg commit -m 'CE'
- $ hg log -G # keep track of phase because I saw some strange bug during developement
- @ 6 default celeste draft CE
- |
- | o 5 default babar draft CD
- |/
- | o 4 mountain public CC
- |/
- | o 1 default public CB
- |/
- o 0 default public CA
-
-
-Pushing a new topic to a non publishing server without topic -> new head
-
- $ cat << EOF >> ../draft/.hg/hgrc
- > [extensions]
- > topic=!
- > EOF
- $ hg push ssh://user@dummy/draft
- pushing to ssh://user@dummy/draft
- searching for changes
- abort: push creates new remote head 84eaf32db6c3!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
- $ hg log -G
- @ 6 default celeste draft CE
- |
- | o 5 default babar draft CD
- |/
- | o 4 mountain public CC
- |/
- | o 1 default public CB
- |/
- o 0 default public CA
-
-
-Pushing a new topic to a non publishing server should not be seen as a new head
-
- $ printf "topic=" >> ../draft/.hg/hgrc
- $ hg config extensions.topic >> ../draft/.hg/hgrc
- $ hg push ssh://user@dummy/draft
- pushing to ssh://user@dummy/draft
- 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)
- $ hg log -G
- @ 6 default celeste draft CE
- |
- | o 5 default babar draft CD
- |/
- | o 4 mountain public CC
- |/
- | o 1 default public CB
- |/
- o 0 default public CA
-
-
-Pushing a new topic to a publishing server should be seen as a new head
-
- $ hg push ssh://user@dummy/main
- pushing to ssh://user@dummy/main
- searching for changes
- abort: push creates new remote head 67f579af159d!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
- $ hg log -G
- @ 6 default celeste draft CE
- |
- | o 5 default babar draft CD
- |/
- | o 4 mountain public CC
- |/
- | o 1 default public CB
- |/
- o 0 default public CA
-
-
-Check that we reject multiple head on the same topic
-----------------------------------------------------
-
- $ hg up 'desc(CB)'
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg topic babar
- $ echo aaa > fff
- $ hg add fff
- $ hg commit -m 'CF'
- $ hg log -G
- @ 7 default babar draft CF
- |
- | o 6 default celeste draft CE
- | |
- | | o 5 default babar draft CD
- | |/
- | | o 4 mountain public CC
- | |/
- o | 1 default public CB
- |/
- o 0 default public CA
-
-
- $ hg push draft
- pushing to $TESTTMP/draft (glob)
- searching for changes
- abort: push creates new remote head f0bc62a661be on branch 'default:babar'!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
-
-Multiple head on a branch merged in a topic changesets
-------------------------------------------------------------------------
-
-
- $ hg up 'desc(CA)'
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ echo aaa > ggg
- $ hg add ggg
- $ hg commit -m 'CG'
- created new head
- $ hg up 'desc(CF)'
- switching to topic babar
- 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg merge 'desc(CG)'
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- (branch merge, don't forget to commit)
- $ hg commit -m 'CM'
- $ hg log -G
- @ 9 default babar draft CM
- |\
- | o 8 default draft CG
- | |
- o | 7 default babar draft CF
- | |
- | | o 6 default celeste draft CE
- | |/
- | | o 5 default babar draft CD
- | |/
- | | o 4 mountain public CC
- | |/
- o | 1 default public CB
- |/
- o 0 default public CA
-
-
-Reject when pushing to draft
-
- $ hg push draft -r .
- pushing to $TESTTMP/draft (glob)
- searching for changes
- abort: push creates new remote head 4937c4cad39e!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
-
-
-Reject when pushing to publishing
-
- $ hg push -r .
- pushing to $TESTTMP/main (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 2 changes to 2 files
-
- $ cd ..
-
-Test phase move
-==================================
-
-setup, two repo knowns about two small topic branch
-
- $ hg init repoA
- $ hg clone repoA repoB
- updating to branch default
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ cat << EOF >> repoA/.hg/hgrc
- > [phases]
- > publish=False
- > EOF
- $ cat << EOF >> repoB/.hg/hgrc
- > [phases]
- > publish=False
- > EOF
- $ cd repoA
- $ echo aaa > base
- $ hg add base
- $ hg commit -m 'CBASE'
- $ echo aaa > aaa
- $ hg add aaa
- $ hg topic topicA
- $ hg commit -m 'CA'
- $ hg up 'desc(CBASE)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ echo aaa > bbb
- $ hg add bbb
- $ hg topic topicB
- $ hg commit -m 'CB'
- $ cd ..
- $ hg push -R repoA repoB
- pushing to repoB
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 3 changes to 3 files (+1 heads)
- $ hg log -G -R repoA
- @ 2 default topicB draft CB
- |
- | o 1 default topicA draft CA
- |/
- o 0 default draft CBASE
-
-
-We turn different topic to public on each side,
-
- $ hg -R repoA phase --public topicA
- $ hg -R repoB phase --public topicB
-
-Pushing should complain because it create to heads on default
-
- $ hg push -R repoA repoB
- pushing to repoB
- searching for changes
- no changes found
- abort: push create a new head on branch "default"
- [255]
--- a/tests/test-topic-stack-data.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,270 +0,0 @@
-Setup
-=====
-
- $ . "$TESTDIR/testlib/topic_setup.sh"
-
- $ hg init test-list
- $ cd test-list
- $ cat <<EOF >> .hg/hgrc
- > [phases]
- > publish=false
- > EOF
- $ cat <<EOF >> $HGRCPATH
- > [experimental]
- > # disable the new graph style until we drop 3.7 support
- > graphstyle.missing = |
- > # turn evolution on
- > evolution=all
- > EOF
-
-
- $ mkcommit() {
- > echo "$1" > "$1"
- > hg add "$1"
- > hg ci -m "add $1"
- > }
-
-Build some basic graph
-----------------------
-
- $ for x in base_a base_b base_c base_d base_e ; do
- > mkcommit $x
- > done
-
-Add another branch with two heads
-
- $ hg up 'desc(base_a)'
- 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
- $ hg branch lake
- marked working directory as branch lake
- (branches are permanent and global, did you want a bookmark?)
- $ mkcommit lake_a
- $ mkcommit lake_b
- $ hg up 'desc(lake_a)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ mkcommit lake_c
- created new head
-
-
-Add some topics
----------------
-
-A simple topic that need rebasing
-
- $ hg up 'desc(base_c)'
- 2 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ hg topic baz
- $ mkcommit baz_a
- $ mkcommit baz_b
-
-A simple topic with unstability
-
- $ hg up 'desc(base_d)'
- 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ hg topic fuz
- $ mkcommit fuz_a
- $ mkcommit fuz_b
- $ mkcommit fuz_c
- $ hg up 'desc(fuz_a)'
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ hg commit --amend --message 'fuz1_a'
-
-A topic with multiple heads
-
- $ hg up 'desc(base_e)'
- 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg topic bar
- $ mkcommit bar_a
- $ mkcommit bar_b
- $ mkcommit bar_c
- $ hg up 'desc(bar_b)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ mkcommit bar_d
- $ mkcommit bar_e
- $ hg up 'desc(bar_d)'
- 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
- $ hg commit --amend --message 'bar1_d'
-
-topic 'foo' on the multi headed branch
-
- $ hg up 'desc(lake_a)'
- 1 files updated, 0 files merged, 7 files removed, 0 files unresolved
- $ hg topic foo
- $ mkcommit foo_a
- $ mkcommit foo_b
-
-Summary
--------
-
- $ hg summary
- parent: 21:3e54b49a3113 tip
- add foo_b
- branch: lake
- commit: (clean)
- update: 2 new changesets (update)
- phases: 22 draft
- unstable: 3 changesets
- topic: foo
- $ hg log --graph -T '{desc} ({branch}) [{topic}]'
- @ add foo_b (lake) []
- |
- o add foo_a (lake) []
- |
- | o bar1_d (default) []
- | |
- | | o add bar_e (default) []
- | | |
- | | x add bar_d (default) []
- | |/
- | | o add bar_c (default) []
- | |/
- | o add bar_b (default) []
- | |
- | o add bar_a (default) []
- | |
- | | o fuz1_a (default) []
- | | |
- | | | o add fuz_c (default) []
- | | | |
- | | | o add fuz_b (default) []
- | | | |
- | | | x add fuz_a (default) []
- | | |/
- | | | o add baz_b (default) []
- | | | |
- | | | o add baz_a (default) []
- | | | |
- +-------o add lake_c (lake) []
- | | | |
- +-------o add lake_b (lake) []
- | | | |
- o | | | add lake_a (lake) []
- | | | |
- | o | | add base_e (default) []
- | |/ /
- | o / add base_d (default) []
- | |/
- | o add base_c (default) []
- | |
- | o add base_b (default) []
- |/
- o add base_a (default) []
-
-
-Actual Testing
-==============
-
-basic output
-
- $ hg topic
- bar
- baz
- * foo
- fuz
-
-quiet version
-
- $ hg topic --quiet
- bar
- baz
- foo
- fuz
-
-verbose
-
- $ hg topic --verbose
- bar (on branch: default, 5 changesets, 1 troubled, 2 heads)
- baz (on branch: default, 2 changesets, 2 behind)
- * foo (on branch: lake, 2 changesets, ambiguous destination)
- fuz (on branch: default, 3 changesets, 2 troubled, 1 behind)
-
-json
-
- $ hg topic -T json
- [
- {
- "active": false,
- "topic": "bar"
- },
- {
- "active": false,
- "topic": "baz"
- },
- {
- "active": true,
- "topic": "foo"
- },
- {
- "active": false,
- "topic": "fuz"
- }
- ]
-
-json --verbose
-
- $ hg topic -T json --verbose
- [
- {
- "active": false,
- "branches+": "default",
- "changesetcount": 5,
- "headcount": 2,
- "topic": "bar",
- "troubledcount": 1
- },
- {
- "active": false,
- "behindcount": 2,
- "branches+": "default",
- "changesetcount": 2,
- "topic": "baz"
- },
- {
- "active": true,
- "behinderror": "ambiguous destination",
- "branches+": "lake",
- "changesetcount": 2,
- "topic": "foo"
- },
- {
- "active": false,
- "behindcount": 1,
- "branches+": "default",
- "changesetcount": 3,
- "topic": "fuz",
- "troubledcount": 2
- }
- ]
-
-Also test this situation with 'hg stack'
-=======================================
-
- $ hg stack bar
- ### topic: bar (2 heads)
- ### branch: default
- t5: add bar_c
- t2^ add bar_b (base)
- t4$ add bar_e (unstable)
- t3: bar1_d
- t2: add bar_b
- t1: add bar_a
- ^ add base_e
- $ hg stack baz
- ### topic: baz
- ### branch: default, 2 behind
- t2: add baz_b
- t1: add baz_a
- ^ add base_c
- $ hg stack foo
- ### topic: foo
- ### branch: lake, ambigious rebase destination
- t2@ add foo_b (current)
- t1: add foo_a
- ^ add lake_a
- $ hg stack fuz
- ### topic: fuz
- ### branch: default, 1 behind
- t3$ add fuz_c (unstable)
- t2$ add fuz_b (unstable)
- t1: fuz1_a
- ^ add base_d
--- a/tests/test-topic-stack.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,254 +0,0 @@
- $ . "$TESTDIR/testlib/topic_setup.sh"
-
-Initial setup
-
-
- $ cat << EOF >> $HGRCPATH
- > [ui]
- > logtemplate = {rev} {branch} \{{get(namespaces, "topics")}} {phase} {desc|firstline}\n
- > [experimental]
- > evolution=createmarkers,exchange,allowunstable
- > EOF
-
- $ hg init main
- $ cd main
- $ hg topic other
- $ echo aaa > aaa
- $ hg add aaa
- $ hg commit -m c_a
- $ echo aaa > bbb
- $ hg add bbb
- $ hg commit -m c_b
- $ hg topic foo
- $ echo aaa > ccc
- $ hg add ccc
- $ hg commit -m c_c
- $ echo aaa > ddd
- $ hg add ddd
- $ hg commit -m c_d
- $ echo aaa > eee
- $ hg add eee
- $ hg commit -m c_e
- $ echo aaa > fff
- $ hg add fff
- $ hg commit -m c_f
- $ hg log -G
- @ 5 default {foo} draft c_f
- |
- o 4 default {foo} draft c_e
- |
- o 3 default {foo} draft c_d
- |
- o 2 default {foo} draft c_c
- |
- o 1 default {other} draft c_b
- |
- o 0 default {other} draft c_a
-
-
-Check that topic without any parent does not crash --list
----------------------------------------------------------
-
- $ hg up other
- switching to topic other
- 0 files updated, 0 files merged, 4 files removed, 0 files unresolved
- $ hg topic --list
- ### topic: other
- ### branch: default
- t2@ c_b (current)
- t1: c_a
- $ hg phase --public 'topic("other")'
- $ hg up foo
- switching to topic foo
- 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-Simple test
------------
-
-'hg stack' list all changeset in the topic
-
- $ hg topic
- * foo
- $ hg stack
- ### topic: foo
- ### branch: default
- t4@ c_f (current)
- t3: c_e
- t2: c_d
- t1: c_c
- ^ c_b
-
-error case, nothing to list
-
- $ hg topic --clear
- $ hg stack
- abort: no active topic to list
- [255]
-
-Test "t#" reference
--------------------
-
-
- $ hg up t2
- abort: cannot resolve "t2": no active topic
- [255]
- $ hg topic foo
- $ hg up t42
- abort: cannot resolve "t42": topic "foo" has only 4 changesets
- [255]
- $ hg up t2
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ hg summary
- parent: 3:e629654d7050
- c_d
- branch: default
- commit: (clean)
- update: (current)
- phases: 4 draft
- topic: foo
-
-Case with some of the topic unstable
-------------------------------------
-
- $ echo bbb > ddd
- $ hg commit --amend
- $ hg log -G
- @ 7 default {foo} draft c_d
- |
- | o 5 default {foo} draft c_f
- | |
- | o 4 default {foo} draft c_e
- | |
- | x 3 default {foo} draft c_d
- |/
- o 2 default {foo} draft c_c
- |
- o 1 default {} public c_b
- |
- o 0 default {} public c_a
-
- $ hg topic --list
- ### topic: foo
- ### branch: default
- t4$ c_f (unstable)
- t3$ c_e (unstable)
- t2@ c_d (current)
- t1: c_c
- ^ c_b
-
-Also test the revset:
-
- $ hg log -r 'stack()'
- 2 default {foo} draft c_c
- 7 default {foo} draft c_d
- 4 default {foo} draft c_e
- 5 default {foo} draft c_f
-
-Case with multiple heads on the topic
--------------------------------------
-
-Make things linear again
-
- $ hg rebase -s 'desc(c_e)' -d 'desc(c_d) - obsolete()'
- rebasing 4:0f9ac936c87d "c_e"
- rebasing 5:6559e6d93aea "c_f"
- $ hg log -G
- o 9 default {foo} draft c_f
- |
- o 8 default {foo} draft c_e
- |
- @ 7 default {foo} draft c_d
- |
- o 2 default {foo} draft c_c
- |
- o 1 default {} public c_b
- |
- o 0 default {} public c_a
-
-
-
-Create the second branch
-
- $ hg up 'desc(c_d)'
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ echo aaa > ggg
- $ hg add ggg
- $ hg commit -m c_g
- $ echo aaa > hhh
- $ hg add hhh
- $ hg commit -m c_h
- $ hg log -G
- @ 11 default {foo} draft c_h
- |
- o 10 default {foo} draft c_g
- |
- | o 9 default {foo} draft c_f
- | |
- | o 8 default {foo} draft c_e
- |/
- o 7 default {foo} draft c_d
- |
- o 2 default {foo} draft c_c
- |
- o 1 default {} public c_b
- |
- o 0 default {} public c_a
-
-
-Test output
-
- $ hg top -l
- ### topic: foo (2 heads)
- ### branch: default
- t6: c_f
- t5: c_e
- t2^ c_d (base)
- t4@ c_h (current)
- t3: c_g
- t2: c_d
- t1: c_c
- ^ c_b
-
-Case with multiple heads on the topic with unstability involved
----------------------------------------------------------------
-
-We amend the message to make sure the display base pick the right changeset
-
- $ hg up 'desc(c_d)'
- 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
- $ echo ccc > ddd
- $ hg commit --amend -m 'c_D'
- $ hg rebase -d . -s 'desc(c_g)'
- rebasing 10:81264ae8a36a "c_g"
- rebasing 11:fde5f5941642 "c_h"
- $ hg log -G
- o 15 default {foo} draft c_h
- |
- o 14 default {foo} draft c_g
- |
- @ 13 default {foo} draft c_D
- |
- | o 9 default {foo} draft c_f
- | |
- | o 8 default {foo} draft c_e
- | |
- | x 7 default {foo} draft c_d
- |/
- o 2 default {foo} draft c_c
- |
- o 1 default {} public c_b
- |
- o 0 default {} public c_a
-
-
- $ hg topic --list
- ### topic: foo (2 heads)
- ### branch: default
- t6$ c_f (unstable)
- t5$ c_e (unstable)
- t2^ c_D (base)
- t4: c_h
- t3: c_g
- t2@ c_D (current)
- t1: c_c
- ^ c_b
--- a/tests/test-topic-tutorial.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-==============
-Topic Tutorial
-==============
-
-.. This test file is also supposed to be able to compile as a rest file.
-
-
-.. Some Setup::
-
- $ . "$TESTDIR/testlib/topic_setup.sh"
- $ hg init server
- $ cd server
- $ cat >> .hg/hgrc << EOF
- > [ui]
- > user= Shopping Master
- > EOF
- $ cat >> shopping << EOF
- > Spam
- > Whizzo butter
- > Albatross
- > Rat (rather a lot)
- > Jugged fish
- > Blancmange
- > Salmon mousse
- > EOF
- $ hg commit -A -m "Shopping list"
- adding shopping
- $ cd ..
- $ hg clone server client
- updating to branch default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ cd client
- $ cat >> .hg/hgrc << EOF
- > [ui]
- > user= Tutorial User
- > EOF
-
-Topic branches are lightweight branches which disappear when changes are
-finalized (move to the public phase). They can help users to organise and share
-their unfinished work.
-
-Topic Basics
-============
-
-Let's says we use Mercurial to manage our shopping list::
-
- $ hg log --graph
- @ changeset: 0:38da43f0a2ea
- tag: tip
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Shopping list
-
-
-We are about to do some edition to this list and would like to do them within
-a topic. Creating a new topic is done using the ``topic`` command::
-
- $ hg topic food
-
-As for named branch, our topic is active but it does not contains any changesets yet::
-
- $ hg topic
- * food
- $ hg summary
- parent: 0:38da43f0a2ea tip
- Shopping list
- branch: default
- commit: (clean)
- update: (current)
- topic: food
- $ hg log --graph
- @ changeset: 0:38da43f0a2ea
- tag: tip
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Shopping list
-
-
-Our next commit will be part of the active topic::
-
- $ cat >> shopping << EOF
- > Egg
- > Suggar
- > Vinegar
- > Oil
- > EOF
- $ hg commit -m "adding condiments"
- $ hg log --graph --rev 'topic("food")'
- @ changeset: 1:13900241408b
- | tag: tip
- ~ topic: food
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: adding condiments
-
-
-And future commit will be part of that topic too::
-
- $ cat >> shopping << EOF
- > Bananas
- > Pear
- > Apple
- > EOF
- $ hg commit -m "adding fruits"
- $ hg log --graph --rev 'topic("food")'
- @ changeset: 2:287de11b401f
- | tag: tip
- | topic: food
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding fruits
- |
- o changeset: 1:13900241408b
- | topic: food
- ~ user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: adding condiments
-
-
-We can get a compact view of the content of our topic using the ``stack`` command::
-
- $ hg stack
- ### topic: food
- ### branch: default
- t2@ adding fruits (current)
- t1: adding condiments
- ^ Shopping list
-
-The topic desactivate when we update away from it::
-
- $ hg up default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg topic
- food
-
-Note that ``default`` (name of the branch) now refers to the tipmost changeset of default without a topic::
-
- $ hg log --graph
- o changeset: 2:287de11b401f
- | tag: tip
- | topic: food
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding fruits
- |
- o changeset: 1:13900241408b
- | topic: food
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding condiments
- |
- @ changeset: 0:38da43f0a2ea
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Shopping list
-
-
-And updating back to the topic reactivate it::
-
- $ hg up food
- switching to topic food
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg topic
- * food
-
-The name used for updating does not affect the activation of the topic, updating to a revision part of a topic will activate it in all cases::
-
- $ hg up default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg up --rev 'desc("condiments")'
- switching to topic food
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg topic
- * food
-
-.. server side activity::
-
- $ cd ../server/
- $ cat > shopping << EOF
- > T-Shirt
- > Trousers
- > Spam
- > Whizzo butter
- > Albatross
- > Rat (rather a lot)
- > Jugged fish
- > Blancmange
- > Salmon mousse
- > EOF
- $ hg commit -A -m "Adding clothes"
- $ cd ../client
-
-Topic will also affect rebase and merge destination. Let's pull the latest update from the main server::
-
- $ hg pull
- pulling from $TESTTMP/server (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files (+1 heads)
- (run 'hg heads' to see heads)
- $ hg log -G
- o changeset: 3:6104862e8b84
- | tag: tip
- | parent: 0:38da43f0a2ea
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Adding clothes
- |
- | o changeset: 2:287de11b401f
- | | topic: food
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: adding fruits
- | |
- | @ changeset: 1:13900241408b
- |/ topic: food
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding condiments
- |
- o changeset: 0:38da43f0a2ea
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Shopping list
-
-
-The topic head will not be considered when merge from the new head of the branch::
-
- $ hg up default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg merge
- abort: branch 'default' has one head - please merge with an explicit rev
- (run 'hg heads' to see all heads)
- [255]
-
-But the topic will see that branch head as a valid destination::
-
- $ hg up food
- switching to topic food
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg rebase
- rebasing 1:13900241408b "adding condiments"
- merging shopping
- rebasing 2:287de11b401f "adding fruits"
- merging shopping
- $ hg log --graph
- @ changeset: 5:2d50db8b5b4c
- | tag: tip
- | topic: food
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding fruits
- |
- o changeset: 4:4011b46eeb33
- | topic: food
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding condiments
- |
- o changeset: 3:6104862e8b84
- | parent: 0:38da43f0a2ea
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Adding clothes
- |
- o changeset: 0:38da43f0a2ea
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Shopping list
-
-
-The topic information will fade out when we publish the changesets::
-
- $ hg topic
- food
- $ hg push
- pushing to $TESTTMP/server (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 2 changesets with 2 changes to 1 files
- 2 new obsolescence markers
- $ hg topic
- $ hg log --graph
- @ changeset: 5:2d50db8b5b4c
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding fruits
- |
- o changeset: 4:4011b46eeb33
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: adding condiments
- |
- o changeset: 3:6104862e8b84
- | parent: 0:38da43f0a2ea
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Adding clothes
- |
- o changeset: 0:38da43f0a2ea
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Shopping list
-
- $ hg up default
- 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-Working with Multiple Topics
-============================
-
-In the above example, topic are not bring much benefit since you only have one
-line of developement. Topic start to be more useful when you have to work on
-multiple features are the same time.
-
-We might go shopping in a hardware store in the same go, so let's add some
-tools to the shopping list withing a new topic::
-
- $ hg topic tools
- $ echo hammer >> shopping
- $ hg ci -m 'Adding hammer'
- $ echo saw >> shopping
- $ hg ci -m 'Adding saw'
- $ echo drill >> shopping
- $ hg ci -m 'Adding drill'
-
-But are not sure to actually go in the hardward store, so in the meantime, we
-want to extend the list with drinks. We go back to the official default branch
-and start a new topic::
-
- $ hg up default
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg topic drinks
- $ echo 'apple juice' >> shopping
- $ hg ci -m 'Adding apple juice'
- $ echo 'orange juice' >> shopping
- $ hg ci -m 'Adding orange juice'
-
-We now have two topics::
-
- $ hg topic
- * drinks
- tools
-
-The information ``hg stack`` command adapt to the active topic::
-
- $ hg stack
- ### topic: drinks
- ### branch: default
- t2@ Adding orange juice (current)
- t1: Adding apple juice
- ^ adding fruits
- $ hg up tools
- switching to topic tools
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg stack
- ### topic: tools
- ### branch: default
- t3@ Adding drill (current)
- t2: Adding saw
- t1: Adding hammer
- ^ adding fruits
-
-They are seen as independant branch by Mercurial. No rebase or merge betwen them will be attempted by default::
-
- $ hg rebase
- nothing to rebase
- [1]
-
-.. server activity::
-
- $ cd ../server
- $ hg up
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ mv shopping foo
- $ echo 'Coat' > shopping
- $ cat foo >> shopping
- $ hg ci -m 'add a coat'
- $ echo 'Coat' > shopping
- $ echo 'Shoes' >> shopping
- $ cat foo >> shopping
- $ hg rm foo
- not removing foo: file is untracked
- [1]
- $ hg ci -m 'add a pair of shoes'
- $ cd ../client
-
-Lets see what other people did in the mean time::
-
- $ hg pull
- pulling from $TESTTMP/server (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 2 changesets with 2 changes to 1 files (+1 heads)
- (run 'hg heads' to see heads)
-
-There is new changes! We can simply use ``hg rebase`` to update our changeset on top of the latest::
-
- $ hg rebase
- rebasing 6:183984ef46d1 "Adding hammer"
- merging shopping
- rebasing 7:cffff85af537 "Adding saw"
- merging shopping
- rebasing 8:34255b455dac "Adding drill"
- merging shopping
-
-But what about the other topic? You can use 'hg topic --verbose' to see information about them::
-
- $ hg topic --verbose
- drinks (on branch: default, 2 changesets, 2 behind)
- tools (on branch: default, 3 changesets)
-
-The "2 behind" is telling you that there is 2 new changesets on the named branch of the topic. You need to merge or rebase to incorporate them.
-
-Pushing that topic would create a new heads will be prevented::
-
- $ hg push --rev drinks
- pushing to $TESTTMP/server (glob)
- searching for changes
- abort: push creates new remote head 70dfa201ed73!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
-
-
-Even after a rebase Pushing all active topics at the same time will complains about the multiple heads it would create on that branch::
-
- $ hg rebase -b drinks
- rebasing 9:8dfa45bd5e0c "Adding apple juice"
- merging shopping
- rebasing 10:70dfa201ed73 "Adding orange juice"
- merging shopping
- switching to topic tools
- $ hg push
- pushing to $TESTTMP/server (glob)
- searching for changes
- abort: push creates new remote head 4cd7c1591a67!
- (merge or see "hg help push" for details about pushing new heads)
- [255]
-
-Publishing only one of them is allowed (as long as it does not create a new branch head has we just saw in the previous case)::
-
- $ hg push -r drinks
- pushing to $TESTTMP/server (glob)
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 2 changesets with 2 changes to 1 files
- 2 new obsolescence markers
-
-The publishing topic has now vanished, and the one still draft is now marked as "behind"::
-
- $ hg topic --verbose
- * tools (on branch: default, 3 changesets, 2 behind)
- $ hg stack
- ### topic: tools
- ### branch: default, 2 behind
- t3@ Adding drill (current)
- t2: Adding saw
- t1: Adding hammer
- ^ add a pair of shoes
-
--- a/tests/test-topic.t Wed May 03 13:23:36 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,654 +0,0 @@
- $ . "$TESTDIR/testlib/topic_setup.sh"
-
- $ hg init pinky
- $ cd pinky
- $ cat <<EOF >> .hg/hgrc
- > [phases]
- > publish=false
- > EOF
- $ cat <<EOF >> $HGRCPATH
- > [experimental]
- > # disable the new graph style until we drop 3.7 support
- > graphstyle.missing = |
- > EOF
-
- $ hg help topics
- hg topics [TOPIC]
-
- View current topic, set current topic, or see all topics.
-
- The --verbose version of this command display various information on the
- state of each topic.
-
- options:
-
- --clear clear active topic if any
- --change VALUE revset of existing revisions to change topic
- -l --list show the stack of changeset in the topic
-
- (some details hidden, use --verbose to show complete help)
- $ hg topics
-
-Test topics interaction with evolution:
-
- $ hg topics --config experimental.evolution=
- $ hg topics --config experimental.evolution= --change . bob
- abort: must have obsolete enabled to use --change
- [255]
-
-Create some changes:
-
- $ for x in alpha beta gamma delta ; do
- > echo file $x >> $x
- > hg addremove
- > hg ci -m "Add file $x"
- > done
- adding alpha
- adding beta
- adding gamma
- adding delta
-
-Still no topics
- $ hg topics
-
-Test commit flag and help text
-
- $ echo stuff >> alpha
- $ HGEDITOR=cat hg ci -t topicflag
-
-
- HG: Enter commit message. Lines beginning with 'HG:' are removed.
- HG: Leave message empty to abort commit.
- HG: --
- HG: user: test
- HG: topic 'topicflag'
- HG: branch 'default'
- HG: changed alpha
- abort: empty commit message
- [255]
- $ hg revert alpha
- $ hg topic
- * topicflag
-
-Make a topic
- $ hg topic narf
- $ hg topics
- * narf
- $ echo topic work >> alpha
- $ hg ci -m 'start on narf'
- $ hg co .^
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg topic fran
- $ hg topics
- * fran
- narf
- $ echo >> fran work >> beta
- $ hg ci -m 'start on fran'
- $ hg co narf
- switching to topic narf
- 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg topic
- fran
- * narf
- $ hg log -r . -T '{topics}\n'
- narf
- $ echo 'narf!!!' >> alpha
- $ hg ci -m 'narf!'
- $ hg log -G
- @ changeset: 6:7c34953036d6
- | tag: tip
- | topic: narf
- | parent: 4:fb147b0b417c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: narf!
- |
- | o changeset: 5:0469d521db49
- | | topic: fran
- | | parent: 3:a53952faf762
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: start on fran
- | |
- o | changeset: 4:fb147b0b417c
- |/ topic: narf
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on narf
- |
- o changeset: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file delta
- |
- o changeset: 2:15d1eb11d2fa
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file gamma
- |
- o changeset: 1:c692ea2c9224
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file beta
- |
- o changeset: 0:c2b7d2f7d14b
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Add file alpha
-
-
-Exchanging of topics:
- $ cd ..
- $ hg init brain
- $ hg -R pinky push -r 4 brain
- pushing to brain
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 5 changesets with 5 changes to 4 files
-
-Export
-
- $ hg -R pinky export
- # HG changeset patch
- # User test
- # Date 0 0
- # Thu Jan 01 00:00:00 1970 +0000
- # Node ID 7c34953036d6a36eae468c550d0592b89ee8bffc
- # Parent fb147b0b417c25ca15547cd945acf51cf8dcaf02
- # EXP-Topic narf
- narf!
-
- diff -r fb147b0b417c -r 7c34953036d6 alpha
- --- a/alpha Thu Jan 01 00:00:00 1970 +0000
- +++ b/alpha Thu Jan 01 00:00:00 1970 +0000
- @@ -1,2 +1,3 @@
- file alpha
- topic work
- +narf!!!
-
-Import
-
- $ hg -R pinky export > narf.diff
- $ hg -R pinky --config extensions.strip= strip .
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- saved backup bundle to $TESTTMP/pinky/.hg/strip-backup/7c34953036d6-1ff3bae2-backup.hg (glob)
- $ hg -R pinky import narf.diff
- applying narf.diff
- $ hg -R pinky log -r .
- changeset: 6:7c34953036d6
- tag: tip
- topic: narf
- parent: 4:fb147b0b417c
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: narf!
-
-Now that we've pushed to brain, the work done on narf is no longer a
-draft, so we won't see that topic name anymore:
-
- $ hg log -R pinky -G
- @ changeset: 6:7c34953036d6
- | tag: tip
- | topic: narf
- | parent: 4:fb147b0b417c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: narf!
- |
- | o changeset: 5:0469d521db49
- | | topic: fran
- | | parent: 3:a53952faf762
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: start on fran
- | |
- o | changeset: 4:fb147b0b417c
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on narf
- |
- o changeset: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file delta
- |
- o changeset: 2:15d1eb11d2fa
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file gamma
- |
- o changeset: 1:c692ea2c9224
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file beta
- |
- o changeset: 0:c2b7d2f7d14b
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Add file alpha
-
- $ cd brain
- $ hg co tip
- 4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-
-Because the change is public, we won't inherit the topic from narf.
-
- $ hg topic
- $ echo what >> alpha
- $ hg topic query
- $ hg ci -m 'what is narf, pinky?'
- $ hg log -Gl2
- @ changeset: 5:c01515cfc331
- | tag: tip
- | topic: query
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: what is narf, pinky?
- |
- o changeset: 4:fb147b0b417c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on narf
- |
- $ hg push -f ../pinky -r query
- pushing to ../pinky
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files (+1 heads)
- $ hg -R ../pinky log -Gl 4
- o changeset: 7:c01515cfc331
- | tag: tip
- | topic: query
- | parent: 4:fb147b0b417c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: what is narf, pinky?
- |
- | @ changeset: 6:7c34953036d6
- |/ topic: narf
- | parent: 4:fb147b0b417c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: narf!
- |
- | o changeset: 5:0469d521db49
- | | topic: fran
- | | parent: 3:a53952faf762
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: start on fran
- | |
- o | changeset: 4:fb147b0b417c
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on narf
- |
- $ hg topics
- * query
- $ cd ../pinky
- $ hg co query
- switching to topic query
- 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ echo answer >> alpha
- $ hg ci -m 'Narf is like `zort` or `poit`!'
- $ hg merge narf
- merging alpha
- warning: conflicts while merging alpha! (edit, then use 'hg resolve --mark')
- 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
- use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon
- [1]
- $ hg revert -r narf alpha
- $ hg resolve -m alpha
- (no more unresolved files)
- $ hg topic narf
- $ hg ci -m 'Finish narf'
- $ hg topics
- fran
- * narf
- query
- $ hg debugnamecomplete # branch:topic here is a buggy side effect
- default
- default:fran
- default:narf
- default:query
- fran
- narf
- query
- tip
- $ hg phase --public narf
-
-POSSIBLE BUG: narf topic stays alive even though we just made all
-narf commits public:
-
- $ hg topics
- fran
- * narf
- $ hg log -Gl 6
- @ changeset: 9:ae074045b7a7
- |\ tag: tip
- | | parent: 8:54c943c1c167
- | | parent: 6:7c34953036d6
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: Finish narf
- | |
- | o changeset: 8:54c943c1c167
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: Narf is like `zort` or `poit`!
- | |
- | o changeset: 7:c01515cfc331
- | | parent: 4:fb147b0b417c
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: what is narf, pinky?
- | |
- o | changeset: 6:7c34953036d6
- |/ parent: 4:fb147b0b417c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: narf!
- |
- | o changeset: 5:0469d521db49
- | | topic: fran
- | | parent: 3:a53952faf762
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: start on fran
- | |
- o | changeset: 4:fb147b0b417c
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on narf
- |
- $ cd ../brain
- $ hg topics
- * query
- $ hg pull ../pinky -r narf
- pulling from ../pinky
- abort: unknown revision 'narf'!
- [255]
- $ hg pull ../pinky -r default
- pulling from ../pinky
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 3 changesets with 3 changes to 1 files
- (run 'hg update' to get a working copy)
- $ hg topics
- * query
-
-We can pull in the draft-phase change and we get the new topic
-
- $ hg pull ../pinky
- pulling from ../pinky
- searching for changes
- adding changesets
- adding manifests
- adding file changes
- added 1 changesets with 1 changes to 1 files (+1 heads)
- (run 'hg heads' to see heads)
- $ hg topics
- fran
- * query
- $ hg log -Gr 'draft()'
- o changeset: 9:0469d521db49
- | tag: tip
- | topic: fran
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
-
-query is not an open topic, so when we clear the current topic it'll
-disappear:
-
- $ hg topics --clear
- $ hg topics
- fran
-
---clear when we don't have an active topic isn't an error:
-
- $ hg topics --clear
-
-Topic revset
- $ hg log -r 'topic()' -G
- o changeset: 9:0469d521db49
- | tag: tip
- | topic: fran
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
- $ hg log -r 'not topic()' -G
- o changeset: 8:ae074045b7a7
- |\ parent: 7:54c943c1c167
- | | parent: 6:7c34953036d6
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: Finish narf
- | |
- | o changeset: 7:54c943c1c167
- | | parent: 5:c01515cfc331
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: Narf is like `zort` or `poit`!
- | |
- o | changeset: 6:7c34953036d6
- | | parent: 4:fb147b0b417c
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: narf!
- | |
- | @ changeset: 5:c01515cfc331
- |/ user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: what is narf, pinky?
- |
- o changeset: 4:fb147b0b417c
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on narf
- |
- o changeset: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file delta
- |
- o changeset: 2:15d1eb11d2fa
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file gamma
- |
- o changeset: 1:c692ea2c9224
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: Add file beta
- |
- o changeset: 0:c2b7d2f7d14b
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: Add file alpha
-
-No matches because narf is already closed:
- $ hg log -r 'topic(narf)' -G
-This regexp should match the topic `fran`:
- $ hg log -r 'topic("re:.ra.")' -G
- o changeset: 9:0469d521db49
- | tag: tip
- | topic: fran
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
-Exact match on fran:
- $ hg log -r 'topic(fran)' -G
- o changeset: 9:0469d521db49
- | tag: tip
- | topic: fran
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
-
-Match current topic:
- $ hg topic
- fran
- $ hg log -r 'topic(.)'
-(no output is expected)
- $ hg co fran
- switching to topic fran
- 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ hg log -r 'topic(.)'
- changeset: 9:0469d521db49
- tag: tip
- topic: fran
- parent: 3:a53952faf762
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: start on fran
-
-
-Deactivate the topic.
- $ hg topics
- * fran
- $ hg topics --clear
- $ echo fran? >> beta
- $ hg ci -m 'fran?'
- created new head
- $ hg log -Gr 'draft()'
- @ changeset: 10:4073470c35e1
- | tag: tip
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: fran?
- |
- o changeset: 9:0469d521db49
- | topic: fran
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
- $ hg topics
- fran
-Changing topic fails if we don't give a topic
- $ hg topic --change 9
- abort: changing topic requires a topic name or --clear
- [255]
-
-Can't change topic of a public change
- $ hg topic --change 1:: --clear
- abort: can't change topic of a public change
- [255]
-
-Can clear topics
- $ hg topic --change 9 --clear
- changed topic on 1 changes
- please run hg evolve --rev "not topic()" now
- $ hg log -Gr 'draft() and not obsolete()'
- o changeset: 11:783930e1d79e
- | tag: tip
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
- | @ changeset: 10:4073470c35e1
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: fran?
- | |
-
-Normally you'd do this with evolve, but we'll use rebase to avoid
-bonus deps in the testsuite.
-
- $ hg rebase -d tip -s .
- rebasing 10:4073470c35e1 "fran?"
-
-Can add a topic to an existing change
- $ hg topic --change 11 wat
- changed topic on 1 changes
- please run hg evolve --rev "topic(wat)" now
- $ hg log -Gr 'draft() and not obsolete()'
- o changeset: 13:d91cd8fd490e
- | tag: tip
- | topic: wat
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
- | @ changeset: 12:d9e32f4c4806
- | | user: test
- | | date: Thu Jan 01 00:00:00 1970 +0000
- | | summary: fran?
- | |
-
-Normally you'd do this with evolve, but we'll use rebase to avoid
-bonus deps in the testsuite.
-
- $ hg rebase -d tip -s .
- rebasing 12:d9e32f4c4806 "fran?"
-
- $ hg log -Gr 'draft()'
- @ changeset: 14:cf24ad8bbef5
- | tag: tip
- | topic: wat
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: fran?
- |
- o changeset: 13:d91cd8fd490e
- | topic: wat
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
-
-Amend a topic
-
- $ hg topic watwat
- $ hg ci --amend
- $ hg log -Gr 'draft()'
- @ changeset: 16:893ffcf66c1f
- | tag: tip
- | topic: watwat
- | parent: 13:d91cd8fd490e
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: fran?
- |
- o changeset: 13:d91cd8fd490e
- | topic: wat
- | parent: 3:a53952faf762
- | user: test
- | date: Thu Jan 01 00:00:00 1970 +0000
- | summary: start on fran
- |
-
-Clear and amend:
-
- $ hg topic --clear
- $ hg ci --amend
- $ hg log -r .
- changeset: 18:a13639e22b65
- tag: tip
- parent: 13:d91cd8fd490e
- user: test
- date: Thu Jan 01 00:00:00 1970 +0000
- summary: fran?
-
-Readding the same topic with topic --change should work:
- $ hg topic --change . watwat
- changed topic on 1 changes