# HG changeset patch # User Pierre-Yves David # Date 1495460076 -7200 # Node ID d517659556cf08e26ec24fc750206c7efefb9612 # Parent e5e502407ab01680dba69833e071335671f72403# Parent 765b2561fa90e103db54704c09d138d8c174a083 test-compat: merge with mercurial-4.1 Nothing to report diff -r 765b2561fa90 -r d517659556cf .hgtags --- a/.hgtags Thu May 18 23:35:16 2017 +0200 +++ b/.hgtags Mon May 22 15:34:36 2017 +0200 @@ -49,3 +49,4 @@ 165ad227993de4e7d819cc6c820d5b9f7b38b80d 6.0.0 5ef112a6eb875633a7925cde61b7d2d9e65b3a56 6.0.1 8510d3fd7c3b312dc731f4c29badc415d504558a 6.1.0 +d4ee0274a8efbaf3d73a659998248c379c61c2bf 6.2.0 diff -r 765b2561fa90 -r d517659556cf README --- a/README Thu May 18 23:35:16 2017 +0200 +++ b/README Mon May 22 15:34:36 2017 +0200 @@ -112,6 +112,16 @@ Changelog ========= +6.2.1 - in progress +------------------- + + - prune: fix a crash related to color handling, + - next: fix a crash related to color handling, + - discovery: document the 'obshashrange' experiment, + - cache: reduce the warming load in case of reset, + - cache: add a 'experimental.obshashcache.warm-cache' option to allow + disabling post transaction cache warming. + 6.2.0 -- 2017-05-18 ------------------- diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/__init__.py --- a/hgext3rd/evolve/__init__.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/__init__.py Mon May 22 15:34:36 2017 +0200 @@ -44,9 +44,34 @@ # * abort: abort the push auto-publish = ignore +Obsolescence Markers Discovery Experiment +========================================= + +We are experimenting with a new protocol to discover common markers during the +local and remote repository. This experiment is still at an early stage but is +already raising better result than the previous version when usable. + +Large" repositories (hundreds of thousand) are currently unsupported. Some key +algorithm has a naive implementation with too agressive caching, creating +memory consumption issue (this will get fixed). + +Medium sized repositories works fine, but be prepared for a noticable initial +cache filling. for the Mercurial repository, this is around 20 seconds + +The following config control the experiment:: + + [experimental] + + # enable new discovery protocol + # (needed on both client and server) + obshashrange = yes + + # avoid cache warming after transaction + # (recommended 'off' for developer repositories) + # (recommended 'yes' for server (default)) + obshashrange.warm-cache = no """ - evolutionhelptext = """ Obsolescence markers make it possible to mark changesets that have been deleted or superset in a new version of the changeset. @@ -120,6 +145,7 @@ commands, context, copies, + dirstate, error, extensions, help, @@ -196,6 +222,29 @@ reposetup = eh.final_reposetup cmdtable = eh.cmdtable +# pre hg 4.0 compat + +if not util.safehasattr(dirstate.dirstate, 'parentchange'): + import contextlib + + @contextlib.contextmanager + def parentchange(self): + '''Context manager for handling dirstate parents. + + If an exception occurs in the scope of the context manager, + the incoherent dirstate won't be written when wlock is + released. + ''' + self._parentwriters += 1 + yield + # Typically we want the "undo" step of a context manager in a + # finally block so it happens even when an exception + # occurs. In this case, however, we only want to decrement + # parentwriters if the code in the with statement exits + # normally, so we don't have a try/finally here on purpose. + self._parentwriters -= 1 + dirstate.dirstate.parentchange = parentchange + ##################################################################### ### Option configuration ### ##################################################################### @@ -841,12 +890,11 @@ '(see hg help resolve)')) nodenew = _relocatecommit(repo, orig, commitmsg) except error.Abort as exc: - repo.dirstate.beginparentchange() - repo.setparents(repo['.'].node(), nullid) - repo.dirstate.write(tr) - # fix up dirstate for copies and renames - copies.duplicatecopies(repo, dest.rev(), orig.p1().rev()) - repo.dirstate.endparentchange() + with repo.dirstate.parentchange(): + repo.setparents(repo['.'].node(), nullid) + repo.dirstate.write(tr) + # fix up dirstate for copies and renames + copies.duplicatecopies(repo, dest.rev(), orig.p1().rev()) class LocalMergeFailure(MergeFailure, exc.__class__): pass @@ -1755,9 +1803,8 @@ bmupdate(newid) repo.ui.status(_('committed as %s\n') % node.short(newid)) # reroute the working copy parent to the new changeset - repo.dirstate.beginparentchange() - repo.dirstate.setparents(newid, node.nullid) - repo.dirstate.endparentchange() + with repo.dirstate.parentchange(): + repo.dirstate.setparents(newid, node.nullid) def _solvedivergent(ui, repo, divergent, dryrun=False, confirm=False, progresscb=None): @@ -1857,9 +1904,8 @@ assert tr is not None try: repo.ui.setconfig('ui', 'allowemptycommit', True, 'evolve') - repo.dirstate.beginparentchange() - repo.dirstate.setparents(divergent.node(), node.nullid) - repo.dirstate.endparentchange() + with repo.dirstate.parentchange(): + repo.dirstate.setparents(divergent.node(), node.nullid) oldlen = len(repo) amend(ui, repo, message='', logfile='') if oldlen == len(repo): @@ -2064,7 +2110,7 @@ False, lambda: None, category='unstable') if not result: ui.status(_('working directory now at %s\n') - % ui.label(repo['.'], 'evolve.node')) + % ui.label(str(repo['.']), 'evolve.node')) return result return 1 return result @@ -2271,7 +2317,7 @@ repo._bookmarks.recordchange(tr) commands.update(ui, repo, newnode.rev()) ui.status(_('working directory now at %s\n') - % ui.label(newnode, 'evolve.node')) + % ui.label(str(newnode), 'evolve.node')) if movebookmark: bookmarksmod.activate(repo, bookactive) @@ -2512,10 +2558,9 @@ # Move local changes on filtered changeset obsolete.createmarkers(repo, [(old, (repo[newid],))]) phases.retractboundary(repo, tr, oldphase, [newid]) - repo.dirstate.beginparentchange() - repo.dirstate.setparents(newid, node.nullid) - _uncommitdirstate(repo, old, match) - repo.dirstate.endparentchange() + with repo.dirstate.parentchange(): + repo.dirstate.setparents(newid, node.nullid) + _uncommitdirstate(repo, old, match) updatebookmarks(newid) if not repo[newid].files(): ui.warn(_("new changeset is empty\n")) @@ -2748,9 +2793,8 @@ obsolete.createmarkers(repo, [(ctx, (repo[new],))]) phases.retractboundary(repo, tr, ctx.phase(), [new]) if ctx in repo[None].parents(): - repo.dirstate.beginparentchange() - repo.dirstate.setparents(new, node.nullid) - repo.dirstate.endparentchange() + with repo.dirstate.parentchange(): + repo.dirstate.setparents(new, node.nullid) tr.close() finally: lockmod.release(tr, lock, wlock) diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/exthelper.py --- a/hgext3rd/evolve/exthelper.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/exthelper.py Mon May 22 15:34:36 2017 +0200 @@ -3,13 +3,20 @@ ##################################################################### from mercurial import ( - cmdutil, commands, extensions, + registrar, revset, templatekw, + util, ) +if util.safehasattr(registrar, 'command'): + command = registrar.command +else: # compat with hg < 4.3 + from mercurial import cmdutil + command = cmdutil.command + class exthelper(object): """Helper for modular extension setup @@ -30,7 +37,7 @@ self._functionwrappers = [] self._duckpunchers = [] self.cmdtable = {} - self.command = cmdutil.command(self.cmdtable) + self.command = command(self.cmdtable) def merge(self, other): self._uicallables.extend(other._uicallables) diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/hack/directaccess.py --- a/hgext3rd/evolve/hack/directaccess.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/hack/directaccess.py Mon May 22 15:34:36 2017 +0200 @@ -6,9 +6,9 @@ to xxx. """ from mercurial import extensions -from mercurial import cmdutil from mercurial import repoview from mercurial import branchmap +from mercurial import registrar from mercurial import revset from mercurial import error from mercurial import commands @@ -17,7 +17,12 @@ from mercurial.i18n import _ cmdtable = {} -command = cmdutil.command(cmdtable) + +if util.safehasattr(registrar, 'command'): + command = registrar.command(cmdtable) +else: # compat with hg < 4.3 + from mercurial import cmdutil + command = cmdutil.command(cmdtable) # By default, all the commands have directaccess with warnings # List of commands that have no directaccess and directaccess with no warning diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/hack/drophack.py --- a/hgext3rd/evolve/hack/drophack.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/hack/drophack.py Mon May 22 15:34:36 2017 +0200 @@ -12,7 +12,7 @@ import contextlib from mercurial.i18n import _ -from mercurial import cmdutil +from mercurial import registrar from mercurial import repair from mercurial import scmutil from mercurial import lock as lockmod @@ -20,7 +20,12 @@ from mercurial import commands cmdtable = {} -command = cmdutil.command(cmdtable) + +if util.safehasattr(registrar, 'command'): + command = registrar.command(cmdtable) +else: # compat with hg < 4.3 + from mercurial import cmdutil + command = cmdutil.command(cmdtable) @contextlib.contextmanager diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/hack/inhibit.py --- a/hgext3rd/evolve/hack/inhibit.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/hack/inhibit.py Mon May 22 15:34:36 2017 +0200 @@ -14,20 +14,25 @@ However as the inhibitor are not fitting in an append only model, this is incompatible with sharing mutable history. """ -from mercurial import localrepo -from mercurial import obsolete -from mercurial import extensions -from mercurial import cmdutil +from mercurial import bookmarks +from mercurial import commands from mercurial import error +from mercurial import extensions +from mercurial import localrepo +from mercurial import lock as lockmod +from mercurial import obsolete +from mercurial import registrar from mercurial import scmutil -from mercurial import commands -from mercurial import lock as lockmod -from mercurial import bookmarks from mercurial import util from mercurial.i18n import _ cmdtable = {} -command = cmdutil.command(cmdtable) + +if util.safehasattr(registrar, 'command'): + command = registrar.command(cmdtable) +else: # compat with hg < 4.3 + from mercurial import cmdutil + command = cmdutil.command(cmdtable) def _inhibitenabled(repo): return util.safehasattr(repo, '_obsinhibit') @@ -176,14 +181,14 @@ finally: tr.release() -def _createmarkers(orig, repo, relations, flag=0, date=None, metadata=None): +def _createmarkers(orig, repo, relations, *args, **kwargs): """wrap markers create to make sure we de-inhibit target nodes""" # wrapping transactio to unify the one in each function lock = tr = None try: lock = repo.lock() tr = repo.transaction('add-obsolescence-marker') - orig(repo, relations, flag, date, metadata) + orig(repo, relations, *args, **kwargs) precs = (r[0].node() for r in relations) _deinhibitmarkers(repo, precs) tr.close() diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/legacy.py --- a/hgext3rd/evolve/legacy.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/legacy.py Mon May 22 15:34:36 2017 +0200 @@ -24,12 +24,17 @@ import sys import json -from mercurial import cmdutil from mercurial.i18n import _ from mercurial import lock as lockmod from mercurial.node import bin, nullid +from mercurial import registrar from mercurial import util +if util.safehasattr(registrar, 'command'): + commandfunc = registrar.command +else: # compat with hg < 4.3 + from mercurial import cmdutil + commandfunc = cmdutil.command ##################################################################### ### Older format management ### @@ -75,7 +80,7 @@ return rels cmdtable = {} -command = cmdutil.command(cmdtable) +command = commandfunc(cmdtable) @command('debugconvertobsolete', [], '') def cmddebugconvertobsolete(ui, repo): """import markers from an .hg/obsolete-relations file""" diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/metadata.py --- a/hgext3rd/evolve/metadata.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/metadata.py Mon May 22 15:34:36 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.2.0' +__version__ = '6.2.1.dev' testedwith = '3.8.4 3.9.2 4.0.2 4.1.2 4.2' minimumhgversion = '3.8' buglink = 'https://bz.mercurial-scm.org/' diff -r 765b2561fa90 -r d517659556cf hgext3rd/evolve/obsdiscovery.py --- a/hgext3rd/evolve/obsdiscovery.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/evolve/obsdiscovery.py Mon May 22 15:34:36 2017 +0200 @@ -523,12 +523,17 @@ con = self._con if con is not None: con.execute(_reset) - # rewarm the whole cache + # rewarm key revisions + # + # (The current invalidation is too wide, but rewarming every single + # revision is quite costly) + newrevs = [] stop = self._cachekey[0] # tiprev - if revs: - stop = max(revs) - if 0 <= stop: - revs = repo.changelog.revs(stop=stop) + for h in repo.filtered('immutable').changelog.headrevs(): + if h <= stop: + newrevs.append(h) + newrevs.extend(revs) + revs = newrevs # warm the cache for the new revs for r in revs: @@ -672,7 +677,12 @@ repo = reporef() if repo is None: return - if not repo.ui.configbool('experimental', 'obshashrange', False): + hasobshashrange = repo.ui.configbool('experimental', + 'obshashrange', False) + hascachewarm = repo.ui.configbool('experimental', + 'obshashrange.warm-cache', + True) + if not (hasobshashrange and hascachewarm): return repo = repo.unfiltered() # As pointed in 'obscache.update', we could have the changelog diff -r 765b2561fa90 -r d517659556cf hgext3rd/topic/__init__.py --- a/hgext3rd/topic/__init__.py Thu May 18 23:35:16 2017 +0200 +++ b/hgext3rd/topic/__init__.py Mon May 22 15:34:36 2017 +0200 @@ -69,6 +69,7 @@ obsolete, patch, phases, + registrar, util, ) @@ -81,8 +82,13 @@ discovery, ) +if util.safehasattr(registrar, 'command'): + commandfunc = registrar.command +else: # compat with hg < 4.3 + commandfunc = cmdutil.command + cmdtable = {} -command = cmdutil.command(cmdtable) +command = commandfunc(cmdtable) colortable = {'topic.active': 'green', 'topic.list.troubledcount': 'red', 'topic.list.headcount.multiple': 'yellow', diff -r 765b2561fa90 -r d517659556cf tests/test-discovery-obshashrange.t --- a/tests/test-discovery-obshashrange.t Thu May 18 23:35:16 2017 +0200 +++ b/tests/test-discovery-obshashrange.t Mon May 22 15:34:36 2017 +0200 @@ -76,7 +76,7 @@ $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa `getid 'desc(r1)'` $ hg debugobsolete bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb `getid 'desc(r2)'` $ hg debugobsolete cccccccccccccccccccccccccccccccccccccccc `getid 'desc(r4)'` - $ hg debugobsolete dddddddddddddddddddddddddddddddddddddddd `getid 'desc(r5)'` + $ hg debugobsolete dddddddddddddddddddddddddddddddddddddddd `getid 'desc(r5)'` --config experimental.obshashrange.warm-cache=0 $ hg debugobsolete eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee `getid 'desc(r7)'` $ hg debugobsolete aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 66f7d451a68b85ed82ff5fcc254daf50c74144bd 0 (Thu Jan 01 00:00:00 1970 +0000) {'user': 'test'} @@ -109,14 +109,12 @@ * @0000000000000000000000000000000000000000 (*)> debugobsolete cccccccccccccccccccccccccccccccccccccccc bebd167eb94d257ace0e814aeb98e6972ed2970d 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 (*)> debugobsolete dddddddddddddddddddddddddddddddddddddddd c8d03c1b5e94af74b772900c58259d2e08917735 --config experimental.obshashrange.warm-cache=0 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-obshashrange in *.???? seconds (0r, 2o) (glob) * @0000000000000000000000000000000000000000 (*)> updated evo-ext-obscache in *.???? seconds (0r, 1o) (glob) * @0000000000000000000000000000000000000000 (*)> debugobsolete eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee 4de32a90b66cd083ebf3c00b41277aa7abca51dd exited 0 after *.?? seconds (glob) * @0000000000000000000000000000000000000000 (*)> debugobsolete (glob) diff -r 765b2561fa90 -r d517659556cf tests/test-prev-next.t --- a/tests/test-prev-next.t Thu May 18 23:35:16 2017 +0200 +++ b/tests/test-prev-next.t Mon May 22 15:34:36 2017 +0200 @@ -171,10 +171,13 @@ atop:[3] added b (2) hg rebase -r 4e26ef31f919 -d 9ad178109a19 working directory now at 9ad178109a19 - $ hg next --evolve - move:[2] added c - atop:[3] added b (2) - working directory now at e3b6d5df389b + +(add color output for smoke testing) + + $ hg next --evolve --color debug + move:[[evolve.rev|2]] added c + atop:[[evolve.rev|3]] added b (2) + [ ui.status|working directory now at [evolve.node|e3b6d5df389b]] next with ambiguity diff -r 765b2561fa90 -r d517659556cf tests/test-prune.t --- a/tests/test-prune.t Thu May 18 23:35:16 2017 +0200 +++ b/tests/test-prune.t Mon May 22 15:34:36 2017 +0200 @@ -2,6 +2,7 @@ > [ui] > logtemplate={rev}:{node|short}[{bookmarks}] ({separate('/', obsolete ,phase)}) {desc|firstline}\n > [extensions] + > color = > EOF $ echo "evolve=$(echo $(dirname $TESTDIR))/hgext3rd/evolve/" >> $HGRCPATH @@ -71,10 +72,12 @@ pruning multiple changeset at once - $ hg prune 2: - 0 files updated, 0 files merged, 3 files removed, 0 files unresolved - working directory now at 1f0dee641bb7 - 2 changesets pruned +(add color output to test it does not crash) + + $ hg prune 2: --color debug + [ ui.status|0 files updated, 0 files merged, 3 files removed, 0 files unresolved] + [ ui.status|working directory now at [evolve.node|1f0dee641bb7]] + [ ui.status|2 changesets pruned] $ hg debugobsolete 9d206ffc875e1bc304590549be293be36821e66c 0 {47d2a3944de8b013de3be9578e8e344ea2e6c097} (Sat Dec 15 00:00:00 1979 +0000) {'user': 'blah'} 7c3bad9141dcb46ff89abf5f61856facd56e476c 0 {1f0dee641bb7258c56bd60e93edfa2405381c41e} (*) {'user': 'test'} (glob)