--- a/README Wed May 17 11:47:14 2017 +0200
+++ b/README Wed May 17 14:49:02 2017 +0200
@@ -112,6 +112,17 @@
Changelog
=========
+6.2.0 - in progress
+-------------------
+
+ - add a debugobshistory command to inspect the obs-history of a changeset
+ - topic: have thg display topic name if possible,
+ - obscache: more efficient update in the (rare) case of a transaction adding
+ markers without changesets
+ - obshashrange-cache: update incrementally in the (common) case of a
+ transaction not affecting existing range,
+ - obshashrange-cache: keep the cache mostly warm after each transaction.
+
6.1.1 - in progress
-------------------
--- a/hgext3rd/evolve/__init__.py Wed May 17 11:47:14 2017 +0200
+++ b/hgext3rd/evolve/__init__.py Wed May 17 14:49:02 2017 +0200
@@ -162,6 +162,15 @@
obsexcmsg = utility.obsexcmsg
+colortable = {'evolve.short_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
@@ -3249,3 +3258,109 @@
f.write(orig.topic())
return merge.graft(repo, orig, pctx, ['local', 'graft'], True)
+
+@eh.command(
+ '^debugobshistory',
+ [] + commands.formatteropts,
+ _('hg debugobshistory [OPTION]... [REV]'))
+def debugobshistory(ui, repo, *revs, **opts):
+ revs = scmutil.revrange(repo, revs)
+ fm = ui.formatter('debugobshistory', opts)
+
+ revs.reverse()
+ _debugobshistorysingle(fm, repo, revs)
+
+ fm.end()
+
+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.short_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 = node.short(nodewithoutctx)
+ fm.startitem()
+ fm.write('debugobshistory.node', '%s', hexnode,
+ label="evolve.short_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 = (node.short(succnode) for succnode in sorted(succnodes))
+ nodes = fm.formatlist(shortsnodes, 'debugobshistory.succnodes', sep=', ')
+ fm.write('debugobshistory.succnodes', '%s', nodes,
+ label="evolve.short_node")
+
+ fm.plain("\n")
--- a/hgext3rd/evolve/obscache.py Wed May 17 11:47:14 2017 +0200
+++ b/hgext3rd/evolve/obscache.py Wed May 17 14:49:02 2017 +0200
@@ -13,6 +13,7 @@
import errno
from mercurial import (
+ error,
localrepo,
obsolete,
phases,
@@ -20,6 +21,8 @@
util,
)
+from mercurial.i18n import _
+
from . import (
exthelper,
)
@@ -76,91 +79,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 = util.timer()
+ self._updatefrom(repo, revs, obsmarkers)
+ duration = util.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 +344,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 +358,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 +428,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 +448,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 +457,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:
@@ -392,11 +502,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 17 11:47:14 2017 +0200
+++ b/hgext3rd/evolve/obsdiscovery.py Wed May 17 14:49:02 2017 +0200
@@ -46,6 +46,7 @@
from . import (
exthelper,
+ obscache,
utility,
stablerange,
)
@@ -241,6 +242,7 @@
entry = (h, 0)
addentry(entry)
+ local.obsstore.rangeobshashcache.update(local)
querycount = 0
ui.progress(_("comparing obsmarker with other"), querycount)
overflow = []
@@ -342,6 +344,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 +395,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 +408,121 @@
"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._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
- 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)
+ 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.
+ 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:
+ repo.ui.log('evoext-cache', 'obshashcache reset - '
+ 'new markers affect cached ranges\n')
+ con = self._con
+ if con is not None:
+ con.execute(_reset)
+ break
+ else:
+ continue
+ break
+ else:
+ continue
+ break
+
+ # XXX the current reset is too strong we could just drop the affected range
+
+ # XXX if we reset, we should warm the cache for existing heads (draft and public)
+
+ # 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
@util.propertycache
def _con(self):
@@ -459,7 +531,6 @@
repo = self._repo()
if repo is None:
return None
- cachekey = self._cachekey(repo)
con = sqlite3.connect(self._path)
con.text_factory = str
cur = con.execute(_queryexist)
@@ -467,17 +538,19 @@
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:
@@ -499,26 +572,29 @@
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 +625,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 +667,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)
--- a/hgext3rd/evolve/stablerange.py Wed May 17 11:47:14 2017 +0200
+++ b/hgext3rd/evolve/stablerange.py Wed May 17 14:49:02 2017 +0200
@@ -263,6 +263,7 @@
#
# we use the revnumber as an approximation for depth
ui = repo.ui
+ starttime = util.timer()
if upto is None:
upto = len(cl) - 1
@@ -308,6 +309,10 @@
self._tiprev = upto
self._tipnode = cl.node(upto)
+ duration = util.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
@@ -902,7 +907,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 17 11:47:14 2017 +0200
+++ b/hgext3rd/topic/__init__.py Wed May 17 14:49:02 2017 +0200
@@ -100,6 +100,10 @@
'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'
@@ -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):
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-check-commit.t Wed May 17 14:49:02 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-discovery-obshashrange.t Wed May 17 11:47:14 2017 +0200
+++ b/tests/test-discovery-obshashrange.t Wed May 17 14:49:02 2017 +0200
@@ -6,6 +6,9 @@
$ cat << EOF >> $HGRCPATH
> [extensions]
> hgext3rd.evolve =
+ > blackbox =
+ > [defaults]
+ > blackbox = -l 100
> [experimental]
> obshashrange=1
> verbose-obsolescence-exchange=1
@@ -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,56 @@
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 (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' (glob)
+ * @0000000000000000000000000000000000000000 (*)> writing .hg/cache/tags2 with 0 tags (glob)
+ * @0000000000000000000000000000000000000000 (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 66f7d451a68b85ed82ff5fcc254daf50c74144bd (glob)
+ * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> 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 (*)> log --hidden --template '{node}\n' --rev 'desc(r2)' (glob)
+ * @0000000000000000000000000000000000000000 (*)> log --hidden --template '{node}\n' --rev 'desc(r2)' exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 01241442b3c2bf3211e593b549c655ea65b295e3 (glob)
+ * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> log --hidden --template '{node}\n' --rev 'desc(r4)' (glob)
+ * @0000000000000000000000000000000000000000 (*)> log --hidden --template '{node}\n' --rev 'desc(r4)' exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d (glob)
+ * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> 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 (*)> log --hidden --template '{node}\n' --rev 'desc(r5)' (glob)
+ * @0000000000000000000000000000000000000000 (*)> log --hidden --template '{node}\n' --rev 'desc(r5)' exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete dddddddddddddddddddddddddddddddddddddddd c8d03c1b5e94af74b772900c58259d2e08917735 (glob)
+ * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> log --hidden --template '{node}\n' --rev 'desc(r7)' (glob)
+ * @0000000000000000000000000000000000000000 (*)> log --hidden --template '{node}\n' --rev 'desc(r7)' exited 0 after *.?? seconds (glob)
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 4de32a90b66cd083ebf3c00b41277aa7abca51dd (glob)
+ * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob)
+ * @0000000000000000000000000000000000000000 (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @0000000000000000000000000000000000000000 (*)> 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 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 +166,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'}
@@ -117,6 +215,18 @@
remote: adding file changes
remote: added 1 changesets with 1 changes to 1 files (+1 heads)
remote: 1 new obsolescence markers
+ $ 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 +255,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 +270,55 @@
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 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> log --hidden --template '{node}\n' --rev . (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev . exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete ffffffffffffffffffffffffffffffffffffffff 45f8b879de922f6a6e620ba04205730335b6fc7e (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> obshashcache reset - new markers affect cached ranges (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated evo-ext-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 (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> updated stablerange cache in *.???? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> push -f 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 (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> writing .hg/cache/tags2 with 0 tags (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete 111111111111111aaaaaaaaa1111111111111111 66f7d451a68b85ed82ff5fcc254daf50c74144bd (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> log --hidden --template '{node}\n' --rev 'desc(r3)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r3)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete 22222222222222222bbbbbbbbbbbbb2222222222 2dc09a01254db841290af0538aa52f6f52c776e3 (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> push exited 1 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 +357,27 @@
3 new obsolescence markers
(run 'hg heads' to see heads, 'hg merge' to merge)
+ $ hg -R ../server blackbox
+ * @0000000000000000000000000000000000000000 (*)> debugobsolete --rev '::tip' (glob)
+ * @0000000000000000000000000000000000000000 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 +387,28 @@
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 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> debugobsolete exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log -G exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r4)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r4)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r 6 (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 +419,214 @@
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 (*)> alias 'debugobsolete' expands to 'debugobsolete -d '0 0'' (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 (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> writing .hg/cache/tags2 with 0 tags (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r1)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r3)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r3)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r6)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r6)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r f69452c5b1af6cbaaa56ef50cf94fff5bcc6ca23 (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 (*)> log --hidden --template '{node}\n' --rev 'desc(foo)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(foo)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r4)' (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> log --hidden --template '{node}\n' --rev 'desc(r4)' exited 0 after *.?? seconds (glob)
+ * @45f8b879de922f6a6e620ba04205730335b6fc7e (*)> pull -r bebd167eb94d257ace0e814aeb98e6972ed2970d (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 data stripping
+
+ $ 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 (*)> 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 (*)> 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
--- a/tests/test-evolve-obshistory.t Wed May 17 11:47:14 2017 +0200
+++ b/tests/test-evolve-obshistory.t Wed May 17 14:49:02 2017 +0200
@@ -25,9 +25,11 @@
$ mkcommit ROOT
$ mkcommit A0
$ echo 42 >> A0
- $ hg amend -m "A1"
+ $ hg amend -m "A1
+ >
+ > Better commit message"
$ hg log --hidden -G
- @ changeset: 3:a468dc9b3633
+ @ changeset: 3:4ae3a4151de9
| tag: tip
| parent: 0:ea207398892e
| user: test
@@ -51,15 +53,69 @@
Actual test
-----------
-
+ $ hg debugobshistory 4ae3a4151de9
+ 4ae3a4151de9 (3) A1
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as 4ae3a4151de9 (glob)
+ $ hg debugobshistory 4ae3a4151de9 -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "4ae3a4151de9",
+ "debugobshistory.rev": 3,
+ "debugobshistory.shortdescription": "A1"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "4ae3a4151de9"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory --hidden 471f378eab4c
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as 4ae3a4151de9 (glob)
+ $ hg debugobshistory --hidden 471f378eab4c -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "4ae3a4151de9"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
$ hg update 471f378eab4c
abort: hidden revision '471f378eab4c'!
- (use --hidden to access hidden revisions; successor: a468dc9b3633)
+ (use --hidden to access hidden revisions; successor: 4ae3a4151de9)
[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)
+ (use 'hg evolve' to update to its successor: 4ae3a4151de9)
Test output with pruned commit
==============================
@@ -93,10 +149,59 @@
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
working directory now at 471f378eab4c
1 changesets pruned
+ $ hg log --hidden -G
+ x changeset: 2:0dec01379d3b
+ | tag: tip
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: B0
+ |
+ @ 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 debugobshistory 'desc(B0)' --hidden
+ 0dec01379d3b (2) B0
+ pruned by test (*20*) (glob)
+ $ hg debugobshistory 'desc(B0)' --hidden -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.verb": "pruned"
+ }
+ ],
+ "debugobshistory.node": "0dec01379d3b",
+ "debugobshistory.rev": 2,
+ "debugobshistory.shortdescription": "B0"
+ }
+ ]
+ $ hg debugobshistory 'desc(A0)'
+ 471f378eab4c (1) A0
+ $ hg debugobshistory 'desc(A0)' -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
$ hg up 1
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg up 0dec01379d3b
@@ -195,6 +300,95 @@
Actual test
-----------
+ $ hg debugobshistory 471597cad322 --hidden
+ 471597cad322 (1) A0
+ rewritten by test (*20*) as 337fec4d2edc, f257fde29c7a (glob)
+ $ hg debugobshistory 471597cad322 --hidden -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "337fec4d2edc",
+ "f257fde29c7a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471597cad322",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory 337fec4d2edc
+ 337fec4d2edc (2) A0
+ 471597cad322 (1) A0
+ rewritten by test (*20*) as 337fec4d2edc, f257fde29c7a (glob)
+ $ hg debugobshistory 337fec4d2edc -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "337fec4d2edc",
+ "debugobshistory.rev": 2,
+ "debugobshistory.shortdescription": "A0"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "337fec4d2edc",
+ "f257fde29c7a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471597cad322",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory f257fde29c7a
+ f257fde29c7a (3) A0
+ 471597cad322 (1) A0
+ rewritten by test (*20*) as 337fec4d2edc, f257fde29c7a (glob)
+ $ hg debugobshistory f257fde29c7a -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "f257fde29c7a",
+ "debugobshistory.rev": 3,
+ "debugobshistory.shortdescription": "A0"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "337fec4d2edc",
+ "f257fde29c7a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471597cad322",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
$ hg update 471597cad322
abort: hidden revision '471597cad322'!
(use --hidden to access hidden revisions; successors: 337fec4d2edc, f257fde29c7a)
@@ -357,6 +551,74 @@
Actual test
-----------
+ $ hg debugobshistory de7290d8b885 --hidden
+ de7290d8b885 (1) A0
+ rewritten by test (*20*) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a (glob)
+ $ hg debugobshistory de7290d8b885 --hidden -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "1ae8bc733a14",
+ "337fec4d2edc",
+ "c7f044602e9b",
+ "f257fde29c7a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "de7290d8b885",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory c7f044602e9b
+ c7f044602e9b (5) A0
+ de7290d8b885 (1) A0
+ rewritten by test (*20*) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a (glob)
+ $ hg debugobshistory c7f044602e9b -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "c7f044602e9b",
+ "debugobshistory.rev": 5,
+ "debugobshistory.shortdescription": "A0"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "1ae8bc733a14",
+ "337fec4d2edc",
+ "c7f044602e9b",
+ "f257fde29c7a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "de7290d8b885",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory 2:5
+ 337fec4d2edc (2) A0
+ de7290d8b885 (1) A0
+ rewritten by test (*20*) as 1ae8bc733a14, 337fec4d2edc, c7f044602e9b, f257fde29c7a (glob)
+ f257fde29c7a (3) A0
+ 1ae8bc733a14 (4) A0
+ c7f044602e9b (5) A0
$ hg update de7290d8b885
abort: hidden revision 'de7290d8b885'!
(use --hidden to access hidden revisions; successors: 337fec4d2edc, f257fde29c7a and 2 more)
@@ -423,6 +685,105 @@
Actual test
-----------
+ $ hg debugobshistory --hidden 471f378eab4c
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as eb5a0daa2192 (glob)
+ $ hg debugobshistory --hidden 471f378eab4c -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "eb5a0daa2192"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory --hidden 0dec01379d3b
+ 0dec01379d3b (2) B0
+ rewritten by test (*20*) as eb5a0daa2192 (glob)
+ $ hg debugobshistory --hidden 0dec01379d3b -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "eb5a0daa2192"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "0dec01379d3b",
+ "debugobshistory.rev": 2,
+ "debugobshistory.shortdescription": "B0"
+ }
+ ]
+ $ hg debugobshistory eb5a0daa2192
+ eb5a0daa2192 (3) C0
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as eb5a0daa2192 (glob)
+ 0dec01379d3b (2) B0
+ rewritten by test (*20*) as eb5a0daa2192 (glob)
+ $ hg debugobshistory eb5a0daa2192 -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "eb5a0daa2192",
+ "debugobshistory.rev": 3,
+ "debugobshistory.shortdescription": "C0"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "eb5a0daa2192"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "eb5a0daa2192"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "0dec01379d3b",
+ "debugobshistory.rev": 2,
+ "debugobshistory.shortdescription": "B0"
+ }
+ ]
$ hg update 471f378eab4c
abort: hidden revision '471f378eab4c'!
(use --hidden to access hidden revisions; successor: eb5a0daa2192)
@@ -506,6 +867,128 @@
Actual test
-----------
+ $ hg debugobshistory --hidden 471f378eab4c
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as 65b757b745b9 (glob)
+ rewritten by test (*20*) as fdf9bde5129a (glob)
+ $ hg debugobshistory --hidden 471f378eab4c -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "65b757b745b9"
+ ],
+ "debugobshistory.verb": "rewritten"
+ },
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "fdf9bde5129a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory fdf9bde5129a
+ fdf9bde5129a (2) A1
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as 65b757b745b9 (glob)
+ rewritten by test (*20*) as fdf9bde5129a (glob)
+ $ hg debugobshistory fdf9bde5129a -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "fdf9bde5129a",
+ "debugobshistory.rev": 2,
+ "debugobshistory.shortdescription": "A1"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "65b757b745b9"
+ ],
+ "debugobshistory.verb": "rewritten"
+ },
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "fdf9bde5129a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory 65b757b745b9
+ 65b757b745b9 (3) A2
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as 65b757b745b9 (glob)
+ rewritten by test (*20*) as fdf9bde5129a (glob)
+ $ hg debugobshistory 65b757b745b9 -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "65b757b745b9",
+ "debugobshistory.rev": 3,
+ "debugobshistory.shortdescription": "A2"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "65b757b745b9"
+ ],
+ "debugobshistory.verb": "rewritten"
+ },
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "fdf9bde5129a"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
$ hg update 471f378eab4c
abort: hidden revision '471f378eab4c'!
(use --hidden to access hidden revisions; diverged)
@@ -514,3 +997,312 @@
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)
+
+Test output with amended + folded commit
+========================================
+
+Test setup
+----------
+
+ $ hg init $TESTTMP/local-amend-fold
+ $ cd $TESTTMP/local-amend-fold
+ $ mkcommit ROOT
+ $ mkcommit A0
+ $ mkcommit B0
+ $ hg amend -m "B1"
+ $ hg log --hidden -G
+ @ changeset: 3:b7ea6d14e664
+ | tag: tip
+ | parent: 1:471f378eab4c
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: B1
+ |
+ | x changeset: 2:0dec01379d3b
+ |/ 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(B1)' --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: 4:eb5a0daa2192
+ | tag: tip
+ | parent: 0:ea207398892e
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: C0
+ |
+ | x changeset: 3:b7ea6d14e664
+ | | parent: 1:471f378eab4c
+ | | user: test
+ | | date: Thu Jan 01 00:00:00 1970 +0000
+ | | summary: B1
+ | |
+ | | 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 debugobshistory --hidden 471f378eab4c
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as eb5a0daa2192 (glob)
+ $ hg debugobshistory --hidden 471f378eab4c -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "eb5a0daa2192"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg debugobshistory --hidden 0dec01379d3b
+ 0dec01379d3b (2) B0
+ rewritten by test (*20*) as b7ea6d14e664 (glob)
+ $ hg debugobshistory --hidden 0dec01379d3b -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "b7ea6d14e664"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "0dec01379d3b",
+ "debugobshistory.rev": 2,
+ "debugobshistory.shortdescription": "B0"
+ }
+ ]
+ $ hg debugobshistory eb5a0daa2192
+ eb5a0daa2192 (4) C0
+ b7ea6d14e664 (3) B1
+ rewritten by test (*20*) as eb5a0daa2192 (glob)
+ 0dec01379d3b (2) B0
+ rewritten by test (*20*) as b7ea6d14e664 (glob)
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as eb5a0daa2192 (glob)
+ $ hg debugobshistory eb5a0daa2192 -Tjson | python -m json.tool
+ [
+ {
+ "debugobshistory.markers": [],
+ "debugobshistory.node": "eb5a0daa2192",
+ "debugobshistory.rev": 4,
+ "debugobshistory.shortdescription": "C0"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "eb5a0daa2192"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "b7ea6d14e664",
+ "debugobshistory.rev": 3,
+ "debugobshistory.shortdescription": "B1"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "b7ea6d14e664"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "0dec01379d3b",
+ "debugobshistory.rev": 2,
+ "debugobshistory.shortdescription": "B0"
+ },
+ {
+ "debugobshistory.markers": [
+ {
+ "debugobshistory.marker_date": [
+ *, (glob)
+ 0 (glob)
+ ],
+ "debugobshistory.marker_user": "test",
+ "debugobshistory.succnodes": [
+ "eb5a0daa2192"
+ ],
+ "debugobshistory.verb": "rewritten"
+ }
+ ],
+ "debugobshistory.node": "471f378eab4c",
+ "debugobshistory.rev": 1,
+ "debugobshistory.shortdescription": "A0"
+ }
+ ]
+ $ hg update 471f378eab4c
+ abort: hidden revision '471f378eab4c'!
+ (use --hidden to access hidden revisions; successor: eb5a0daa2192)
+ [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 --hidden 0dec01379d3b
+ 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)
+ $ hg update 0dec01379d3b
+ 0 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)
+ $ hg update --hidden 'desc(B0)'
+ 0 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 pushed and pulled obs markers
+==============================================
+
+Test setup
+----------
+
+ $ hg init $TESTTMP/local-remote-markers-1
+ $ cd $TESTTMP/local-remote-markers-1
+ $ mkcommit ROOT
+ $ mkcommit A0
+ $ hg log --hidden -G
+ @ changeset: 1:471f378eab4c
+ | 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 clone $TESTTMP/local-remote-markers-1 $TESTTMP/local-remote-markers-2
+ updating to branch default
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cd $TESTTMP/local-remote-markers-2
+ $ hg log --hidden -G
+ @ changeset: 1:471f378eab4c
+ | 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
+
+ $ cd $TESTTMP/local-remote-markers-1
+ $ hg amend -m "A1"
+ $ hg amend -m "A2"
+ $ hg log --hidden -G
+ @ changeset: 3:7a230b46bf61
+ | tag: tip
+ | parent: 0:ea207398892e
+ | user: test
+ | date: Thu Jan 01 00:00:00 1970 +0000
+ | summary: A2
+ |
+ | x 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 debugobshistory 7a230b46bf61
+ 7a230b46bf61 (3) A2
+ fdf9bde5129a (2) A1
+ rewritten by test (*20*) as 7a230b46bf61 (glob)
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as fdf9bde5129a (glob)
+ $ cd $TESTTMP/local-remote-markers-2
+ $ hg pull
+ pulling from $TESTTMP/local-remote-markers-1
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 0 changes to 1 files (+1 heads)
+ 2 new obsolescence markers
+ (run 'hg heads' to see heads, 'hg merge' to merge)
+ working directory parent is obsolete! (471f378eab4c)
+ (use 'hg evolve' to update to its successor: 7a230b46bf61)
+ $ hg debugobshistory 7a230b46bf61 --traceback
+ 7a230b46bf61 (2) A2
+ fdf9bde5129a
+ rewritten by test (*20*) as 7a230b46bf61 (glob)
+ 471f378eab4c (1) A0
+ rewritten by test (*20*) as fdf9bde5129a (glob)
+ $ hg debugobshistory 7a230b46bf61 --color=debug
+ [evolve.short_node|7a230b46bf61] [evolve.rev|(2)] [evolve.short_description|A2]
+ [evolve.short_node evolve.missing_change_ctx|fdf9bde5129a]
+ [evolve.verb|rewritten] by [evolve.user|test] [evolve.date|(*20*)] as [evolve.short_node|7a230b46bf61] (glob)
+ [evolve.short_node|471f378eab4c] [evolve.rev|(1)] [evolve.short_description|A0]
+ [evolve.verb|rewritten] by [evolve.user|test] [evolve.date|(*20*)] as [evolve.short_node|fdf9bde5129a] (glob)