Re: Deploying registrar configs in a BC safe way
> On Oct 24, 2017, at 10:25, Durham Goodewrote: > > I've been trying to update our extensions to support the new registrar class, > and one thing I've noticed is that it's not really possible to have code that > works with old versions of mercurial and new versions of mercurial at the > same time, without having devel warnings. I can easily stub out the > registration logic if the registrar module doesn't exist, but I can't leave > the default values on the actual config accessor lines, which old mercurial > versions would need. > > For now I'm just updating our extensions to only work with new mercurial, but > if someone tries to use them with an older version it will cause subtle > failures as the default configs will be different. > > I tried to think of some way to fix this, like by leaving the defaults on the > config access line, but ignoring it somehow, but that sounds funky. Thoughts > on how to fix this? How about making registrar instances on extensions have different behavior from core? e.g. * No devel warnings for e.g. missing default values for a few releases * Arguments to control which devel warnings are issued ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH remotenames] configs: update configs to use registrar
I didn't fill in the commit message on this one. V2 incoming On 10/24/17 2:15 PM, Durham Goode wrote: # HG changeset patch # User Durham Goode# Date 1508879615 25200 # Tue Oct 24 14:13:35 2017 -0700 # Node ID 9ead5c33dd22a9a66cea009bcf76ffd801d5677e # Parent 5fb97b6b3d46fcd4dc1b3cb6be137762eb9e60e7 configs: update configs to use registrar diff --git a/remotenames.py b/remotenames.py --- a/remotenames.py +++ b/remotenames.py @@ -32,12 +32,14 @@ from mercurial import localrepo from mercurial import lock as lockmod from mercurial import namespaces from mercurial import obsutil +from mercurial import registrar from mercurial import repair from mercurial import repoview from mercurial import revset from mercurial import scmutil from mercurial import setdiscovery from mercurial import templatekw +from mercurial import ui as uimod from mercurial import url from mercurial import util from mercurial import vfs as vfsmod @@ -51,12 +53,64 @@ try: except ImportError: smartset = revset +configtable = {} +try: +from mercurial import registrar +if not util.safehasattr(registrar, 'configitem'): +raise ImportError() +# Supported in 4.3+ +configitem = registrar.configitem(configtable) +except ImportError: +# Support older releases that didn't register config defaults +registrar = None +def configitem(section, name, default=None): +configtable[(section, name)] = default + +def configdefault(orig, self, section, name, default=None, + untrusted=False): +if default is None: +default = configtable.get((section, name)) +return orig(self, section, name, default=default, untrusted=untrusted) + +configitem('remotenames', 'alias.default', default=False) +configitem('remotenames', 'allownonfastforward', default=False) +configitem('remotenames', 'bookmarks', default=True) +configitem('remotenames', 'branches', default=True) +configitem('remotenames', 'calculatedistance', default=True) +configitem('remotenames', 'disallowedbookmarks', default=[]) +configitem('remotenames', 'disallowedhint', default=None) +configitem('remotenames', 'disallowedto', default=None) +configitem('remotenames', 'fastheaddiscovery', default=True) +configitem('remotenames', 'forcecompat', default=False) +configitem('remotenames', 'forceto', default=False) +configitem('remotenames', 'hoist', default='default') +configitem('remotenames', 'precachecurrent', default=True) +configitem('remotenames', 'precachedistance', default=True) +configitem('remotenames', 'pushanonheads', default=False) +configitem('remotenames', 'pushrev', default=None) +configitem('remotenames', 'resolvenodes', default=True) +configitem('remotenames', 'selectivepull', default=False) +configitem('remotenames', 'selectivepulldefault', default=[]) +configitem('remotenames', 'suppressbranches', default=False) +configitem('remotenames', 'syncbookmarks', default=False) +configitem('remotenames', 'tracking', default=True) +configitem('remotenames', 'transitionbookmarks', default=[]) +configitem('remotenames', 'transitionmessage', default=None) +configitem('remotenames', 'upstream', default=[]) + # namespace to use when recording an hg journal entry journalremotebookmarktype = 'remotebookmark' # name of the file that is used to mark that transition to selectivepull has # happened _selectivepullenabledfile = 'selectivepullenabled' +def uisetup(ui): +if registrar is None: +if util.safehasattr(uimod.ui, '_config'): +extensions.wrapfunction(uimod.ui, '_config', configdefault) +else: +extensions.wrapfunction(uimod.ui, 'config', configdefault) + def exbookcalcupdate(orig, ui, repo, checkout): '''Return a tuple (targetrev, movemarkfrom) indicating the rev to check out and where to move the active bookmark from, if needed.''' @@ -85,7 +139,7 @@ def expushop(orig, pushop, repo, remote, setattr(pushop, flag, kwargs.pop(flag, None)) def _isselectivepull(ui): -return ui.configbool('remotenames', 'selectivepull', False) +return ui.configbool('remotenames', 'selectivepull') def _getselectivepulldefaultbookmarks(ui): default_books = ui.configlist('remotenames', 'selectivepulldefault') @@ -186,7 +240,7 @@ def exfindcommonheads(orig, ui, local, r # the current remotenames are representative of what's on the server. In the # worst case the data might be slightly out of sync and the server sends us # more data than necessary, but this should be rare. -if not ui.configbool('remotenames', 'fastheaddiscovery', True): +if not ui.configbool('remotenames', 'fastheaddiscovery'): return orig(ui, local, remote, **kwargs) cl = local.changelog @@ -280,7 +334,7 @@ def blockerhook(orig, repo, *args, **kwa return blockers def exupdatefromremote(orig, ui, repo, remotemarks, path, trfunc, explicit=()): -if ui.configbool('remotenames', 'syncbookmarks', False): +
[PATCH remotenames V2] configs: update configs to use registrar
# HG changeset patch # User Durham Goode# Date 1508879721 25200 # Tue Oct 24 14:15:21 2017 -0700 # Node ID c8d9ee2123baadd3ca1b571b3e7acf86ca1e6783 # Parent 5fb97b6b3d46fcd4dc1b3cb6be137762eb9e60e7 configs: update configs to use registrar Upstream now gives devel warnings if configs aren't registered, or if they specify defaults at access time. This updates remotenames to register all it's configs. It tries to be backwards compatible and support older clients who don't have config registering as well, but I haven't tested it well (testing against 4.0 crashes for other incompatibility reasons). diff --git a/remotenames.py b/remotenames.py --- a/remotenames.py +++ b/remotenames.py @@ -32,12 +32,14 @@ from mercurial import localrepo from mercurial import lock as lockmod from mercurial import namespaces from mercurial import obsutil +from mercurial import registrar from mercurial import repair from mercurial import repoview from mercurial import revset from mercurial import scmutil from mercurial import setdiscovery from mercurial import templatekw +from mercurial import ui as uimod from mercurial import url from mercurial import util from mercurial import vfs as vfsmod @@ -51,12 +53,64 @@ try: except ImportError: smartset = revset +configtable = {} +try: +from mercurial import registrar +if not util.safehasattr(registrar, 'configitem'): +raise ImportError() +# Supported in 4.3+ +configitem = registrar.configitem(configtable) +except ImportError: +# Support older releases that didn't register config defaults +registrar = None +def configitem(section, name, default=None): +configtable[(section, name)] = default + +def configdefault(orig, self, section, name, default=None, + untrusted=False): +if default is None: +default = configtable.get((section, name)) +return orig(self, section, name, default=default, untrusted=untrusted) + +configitem('remotenames', 'alias.default', default=False) +configitem('remotenames', 'allownonfastforward', default=False) +configitem('remotenames', 'bookmarks', default=True) +configitem('remotenames', 'branches', default=True) +configitem('remotenames', 'calculatedistance', default=True) +configitem('remotenames', 'disallowedbookmarks', default=[]) +configitem('remotenames', 'disallowedhint', default=None) +configitem('remotenames', 'disallowedto', default=None) +configitem('remotenames', 'fastheaddiscovery', default=True) +configitem('remotenames', 'forcecompat', default=False) +configitem('remotenames', 'forceto', default=False) +configitem('remotenames', 'hoist', default='default') +configitem('remotenames', 'precachecurrent', default=True) +configitem('remotenames', 'precachedistance', default=True) +configitem('remotenames', 'pushanonheads', default=False) +configitem('remotenames', 'pushrev', default=None) +configitem('remotenames', 'resolvenodes', default=True) +configitem('remotenames', 'selectivepull', default=False) +configitem('remotenames', 'selectivepulldefault', default=[]) +configitem('remotenames', 'suppressbranches', default=False) +configitem('remotenames', 'syncbookmarks', default=False) +configitem('remotenames', 'tracking', default=True) +configitem('remotenames', 'transitionbookmarks', default=[]) +configitem('remotenames', 'transitionmessage', default=None) +configitem('remotenames', 'upstream', default=[]) + # namespace to use when recording an hg journal entry journalremotebookmarktype = 'remotebookmark' # name of the file that is used to mark that transition to selectivepull has # happened _selectivepullenabledfile = 'selectivepullenabled' +def uisetup(ui): +if registrar is None: +if util.safehasattr(uimod.ui, '_config'): +extensions.wrapfunction(uimod.ui, '_config', configdefault) +else: +extensions.wrapfunction(uimod.ui, 'config', configdefault) + def exbookcalcupdate(orig, ui, repo, checkout): '''Return a tuple (targetrev, movemarkfrom) indicating the rev to check out and where to move the active bookmark from, if needed.''' @@ -85,7 +139,7 @@ def expushop(orig, pushop, repo, remote, setattr(pushop, flag, kwargs.pop(flag, None)) def _isselectivepull(ui): -return ui.configbool('remotenames', 'selectivepull', False) +return ui.configbool('remotenames', 'selectivepull') def _getselectivepulldefaultbookmarks(ui): default_books = ui.configlist('remotenames', 'selectivepulldefault') @@ -186,7 +240,7 @@ def exfindcommonheads(orig, ui, local, r # the current remotenames are representative of what's on the server. In the # worst case the data might be slightly out of sync and the server sends us # more data than necessary, but this should be rare. -if not ui.configbool('remotenames', 'fastheaddiscovery', True): +if not ui.configbool('remotenames', 'fastheaddiscovery'): return orig(ui, local, remote,
[PATCH remotenames] configs: update configs to use registrar
# HG changeset patch # User Durham Goode# Date 1508879615 25200 # Tue Oct 24 14:13:35 2017 -0700 # Node ID 9ead5c33dd22a9a66cea009bcf76ffd801d5677e # Parent 5fb97b6b3d46fcd4dc1b3cb6be137762eb9e60e7 configs: update configs to use registrar diff --git a/remotenames.py b/remotenames.py --- a/remotenames.py +++ b/remotenames.py @@ -32,12 +32,14 @@ from mercurial import localrepo from mercurial import lock as lockmod from mercurial import namespaces from mercurial import obsutil +from mercurial import registrar from mercurial import repair from mercurial import repoview from mercurial import revset from mercurial import scmutil from mercurial import setdiscovery from mercurial import templatekw +from mercurial import ui as uimod from mercurial import url from mercurial import util from mercurial import vfs as vfsmod @@ -51,12 +53,64 @@ try: except ImportError: smartset = revset +configtable = {} +try: +from mercurial import registrar +if not util.safehasattr(registrar, 'configitem'): +raise ImportError() +# Supported in 4.3+ +configitem = registrar.configitem(configtable) +except ImportError: +# Support older releases that didn't register config defaults +registrar = None +def configitem(section, name, default=None): +configtable[(section, name)] = default + +def configdefault(orig, self, section, name, default=None, + untrusted=False): +if default is None: +default = configtable.get((section, name)) +return orig(self, section, name, default=default, untrusted=untrusted) + +configitem('remotenames', 'alias.default', default=False) +configitem('remotenames', 'allownonfastforward', default=False) +configitem('remotenames', 'bookmarks', default=True) +configitem('remotenames', 'branches', default=True) +configitem('remotenames', 'calculatedistance', default=True) +configitem('remotenames', 'disallowedbookmarks', default=[]) +configitem('remotenames', 'disallowedhint', default=None) +configitem('remotenames', 'disallowedto', default=None) +configitem('remotenames', 'fastheaddiscovery', default=True) +configitem('remotenames', 'forcecompat', default=False) +configitem('remotenames', 'forceto', default=False) +configitem('remotenames', 'hoist', default='default') +configitem('remotenames', 'precachecurrent', default=True) +configitem('remotenames', 'precachedistance', default=True) +configitem('remotenames', 'pushanonheads', default=False) +configitem('remotenames', 'pushrev', default=None) +configitem('remotenames', 'resolvenodes', default=True) +configitem('remotenames', 'selectivepull', default=False) +configitem('remotenames', 'selectivepulldefault', default=[]) +configitem('remotenames', 'suppressbranches', default=False) +configitem('remotenames', 'syncbookmarks', default=False) +configitem('remotenames', 'tracking', default=True) +configitem('remotenames', 'transitionbookmarks', default=[]) +configitem('remotenames', 'transitionmessage', default=None) +configitem('remotenames', 'upstream', default=[]) + # namespace to use when recording an hg journal entry journalremotebookmarktype = 'remotebookmark' # name of the file that is used to mark that transition to selectivepull has # happened _selectivepullenabledfile = 'selectivepullenabled' +def uisetup(ui): +if registrar is None: +if util.safehasattr(uimod.ui, '_config'): +extensions.wrapfunction(uimod.ui, '_config', configdefault) +else: +extensions.wrapfunction(uimod.ui, 'config', configdefault) + def exbookcalcupdate(orig, ui, repo, checkout): '''Return a tuple (targetrev, movemarkfrom) indicating the rev to check out and where to move the active bookmark from, if needed.''' @@ -85,7 +139,7 @@ def expushop(orig, pushop, repo, remote, setattr(pushop, flag, kwargs.pop(flag, None)) def _isselectivepull(ui): -return ui.configbool('remotenames', 'selectivepull', False) +return ui.configbool('remotenames', 'selectivepull') def _getselectivepulldefaultbookmarks(ui): default_books = ui.configlist('remotenames', 'selectivepulldefault') @@ -186,7 +240,7 @@ def exfindcommonheads(orig, ui, local, r # the current remotenames are representative of what's on the server. In the # worst case the data might be slightly out of sync and the server sends us # more data than necessary, but this should be rare. -if not ui.configbool('remotenames', 'fastheaddiscovery', True): +if not ui.configbool('remotenames', 'fastheaddiscovery'): return orig(ui, local, remote, **kwargs) cl = local.changelog @@ -280,7 +334,7 @@ def blockerhook(orig, repo, *args, **kwa return blockers def exupdatefromremote(orig, ui, repo, remotemarks, path, trfunc, explicit=()): -if ui.configbool('remotenames', 'syncbookmarks', False): +if ui.configbool('remotenames', 'syncbookmarks'): return orig(ui, repo, remotemarks,
[Bug 5720] New: Interrupted evolve loses phase
https://bz.mercurial-scm.org/show_bug.cgi?id=5720 Bug ID: 5720 Summary: Interrupted evolve loses phase Product: Mercurial Version: 4.4-rc Hardware: PC OS: Linux Status: UNCONFIRMED Severity: feature Priority: wish Component: evolution Assignee: bugzi...@mercurial-scm.org Reporter: martinv...@google.com CC: mercurial-devel@mercurial-scm.org, pierre-yves.da...@ens-lyon.org $ hg init $ echo a > a $ hg ci -Am a $ echo b > a $ hg ci -m b $ echo c > a $ hg ci -sm c $ hg prev $ echo b2 > a $ hg amend $ hg evolve $ echo c2 > a $ hg resolve -m $ hg evolve -c $ hg log -r . -T '{phase}' draft -- You are receiving this mail because: You are on the CC list for the bug. ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1223: merge: disable path conflict checking by default (issue5716)
sid0 updated this revision to Diff 3082. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1223?vs=3076=3082 REVISION DETAIL https://phab.mercurial-scm.org/D1223 AFFECTED FILES mercurial/configitems.py tests/test-audit-path.t tests/test-commandserver.t tests/test-merge1.t tests/test-pathconflicts-basic.t tests/test-pathconflicts-merge.t tests/test-pathconflicts-update.t tests/test-update-names.t CHANGE DETAILS diff --git a/tests/test-update-names.t b/tests/test-update-names.t --- a/tests/test-update-names.t +++ b/tests/test-update-names.t @@ -50,9 +50,7 @@ $ hg st ? name/file $ hg up 1 - name: untracked directory conflicts with file - abort: untracked files in working directory differ from files in requested revision - [255] + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd .. #if symlink diff --git a/tests/test-pathconflicts-update.t b/tests/test-pathconflicts-update.t --- a/tests/test-pathconflicts-update.t +++ b/tests/test-pathconflicts-update.t @@ -1,3 +1,11 @@ +Path conflict checking is currently disabled by default because of issue5716. +Turn it on for this test. + + $ cat >> $HGRCPATH << EOF + > [experimental] + > merge.checkpathconflicts=True + > EOF + $ hg init repo $ cd repo $ echo base > base @@ -150,4 +158,3 @@ $ hg up file2 --clean 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (activating bookmark file2) - diff --git a/tests/test-pathconflicts-merge.t b/tests/test-pathconflicts-merge.t --- a/tests/test-pathconflicts-merge.t +++ b/tests/test-pathconflicts-merge.t @@ -1,3 +1,11 @@ +Path conflict checking is currently disabled by default because of issue5716. +Turn it on for this test. + + $ cat >> $HGRCPATH << EOF + > [experimental] + > merge.checkpathconflicts=True + > EOF + $ hg init repo $ cd repo $ echo base > base diff --git a/tests/test-pathconflicts-basic.t b/tests/test-pathconflicts-basic.t --- a/tests/test-pathconflicts-basic.t +++ b/tests/test-pathconflicts-basic.t @@ -1,3 +1,11 @@ +Path conflict checking is currently disabled by default because of issue5716. +Turn it on for this test. + + $ cat >> $HGRCPATH << EOF + > [experimental] + > merge.checkpathconflicts=True + > EOF + $ hg init repo $ cd repo $ echo base > base @@ -96,4 +104,3 @@ commit: (clean) update: 1 new changesets, 2 branch heads (merge) phases: 4 draft - diff --git a/tests/test-merge1.t b/tests/test-merge1.t --- a/tests/test-merge1.t +++ b/tests/test-merge1.t @@ -30,22 +30,23 @@ $ mkdir b && touch b/nonempty $ hg up - b: untracked directory conflicts with file - abort: untracked files in working directory differ from files in requested revision - [255] + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg ci nothing changed [1] $ hg sum - parent: 0:538afb845929 - commit #0 + parent: 1:b8bb4a988f25 tip + commit #1 branch: default - commit: 1 unknown (clean) - update: 1 new changesets (update) + commit: (clean) + update: (current) phases: 2 draft - $ rm b/nonempty + +The following line is commented out because the file doesn't exist at the moment, and some OSes error out even with `rm -f`. +$ rm b/nonempty + $ hg up - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + 0 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg sum parent: 1:b8bb4a988f25 tip commit #1 diff --git a/tests/test-commandserver.t b/tests/test-commandserver.t --- a/tests/test-commandserver.t +++ b/tests/test-commandserver.t @@ -975,12 +975,8 @@ *** runcommand up -qC 2 *** runcommand up -qC 1 *** runcommand merge 2 - a: path conflict - a file or link has the same name as a directory - the local file has been renamed to a~aa04623eb0c3 - resolve manually then use 'hg resolve --mark a' - 1 files updated, 0 files merged, 0 files removed, 1 files unresolved - use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon - [1] + abort: path 'a/poisoned' traverses symbolic link 'a' + [255] $ ls ../merge-symlink-out cache of repo.auditor should be discarded, so matcher would never traverse diff --git a/tests/test-audit-path.t b/tests/test-audit-path.t --- a/tests/test-audit-path.t +++ b/tests/test-audit-path.t @@ -104,8 +104,7 @@ back/test #if symlink $ hg update -Cr2 - back: is both a file and a directory - abort: destination manifest contains path conflicts + abort: path 'back/test' traverses symbolic link 'back' [255] #else ('back' will be a file and cause some other system specific error) @@ -167,24 +166,17 @@ $ hg up -qC 1 $ hg merge 2 - a: path conflict - a file or link has the same name as a directory - the local file has been renamed to a~aa04623eb0c3 - resolve manually then use 'hg resolve --mark a' - 1 files updated, 0 files merged, 0 files removed, 1 files unresolved - use
D1222: merge: add a config option to disable path conflict checking
sid0 added a comment. > The debug section doesn't seem to exists, could we use 'experimental' instead while we fix the performance regression? Good idea! Done, thanks! REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1222 To: sid0, #hg-reviewers Cc: lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1222: merge: add a config option to disable path conflict checking
sid0 updated this revision to Diff 3081. REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D1222?vs=3073=3081 REVISION DETAIL https://phab.mercurial-scm.org/D1222 AFFECTED FILES mercurial/configitems.py mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -693,6 +693,7 @@ abortconflicts = set() unknownconfig = _getcheckunknownconfig(repo, 'merge', 'checkunknown') ignoredconfig = _getcheckunknownconfig(repo, 'merge', 'checkignored') +pathconfig = repo.ui.configbool('experimental', 'merge.checkpathconflicts') if not force: def collectconflicts(conflicts, config): if config == 'abort': @@ -704,7 +705,7 @@ if m in ('c', 'dc'): if _checkunknownfile(repo, wctx, mctx, f): fileconflicts.add(f) -elif f not in wctx: +elif pathconfig and f not in wctx: path = _checkunknowndirs(repo, f) if path is not None: pathconflicts.add(path) @@ -1139,8 +1140,9 @@ actions[f] = ('dc', (None, f, f, False, pa.node()), "prompt deleted/changed") -# If we are merging, look for path conflicts. -checkpathconflicts(repo, wctx, p2, actions) +if repo.ui.configbool('experimental', 'merge.checkpathconflicts'): +# If we are merging, look for path conflicts. +checkpathconflicts(repo, wctx, p2, actions) return actions, diverge, renamedelete diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -575,6 +575,9 @@ coreconfigitem('merge', 'checkignored', default='abort', ) +coreconfigitem('experimental', 'merge.checkpathconflicts', +default=True, +) coreconfigitem('merge', 'followcopies', default=True, ) To: sid0, #hg-reviewers Cc: lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
[Bug 5719] New: ctrl-c during `hg push` managed to leave abandoned transaction on a remote repo (possibly bitbucket specific)
https://bz.mercurial-scm.org/show_bug.cgi?id=5719 Bug ID: 5719 Summary: ctrl-c during `hg push` managed to leave abandoned transaction on a remote repo (possibly bitbucket specific) Product: Mercurial Version: default branch Hardware: PC OS: Linux Status: UNCONFIRMED Severity: feature Priority: wish Component: Mercurial Assignee: bugzi...@mercurial-scm.org Reporter: h...@pewpew.net CC: mercurial-devel@mercurial-scm.org Note: this is possibly bitbucket specific, I have not attempted to reproduce. TL;DR: I tried to `hg push -f`, realized I wanted to `hg push -f -r .`, hit Ctrl-C to cancel the original command, and ended up with an abandoned transaction *on the remote repo* that I couldn't clean up. Setup: ≻ hg version -v Mercurial Distributed SCM (version 4.3.3+994-4dc8a2ee0f4f) (see https://mercurial-scm.org for more information) Copyright (C) 2005-2017 Matt Mackall and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Enabled extensions: backupsexternal morestatus external chistedit external google_hgext external 2017.10.11.00 narrowhg external 0.1 remotefilelog external evolve external 6.8.0.dev patience external blackbox internal multidiff external pdb_interrupt external extdiffinternal histedit internal patchbomb internal absorb external graphlog internal rebase internal record internal shelve internal transplant internal Here's a filtered version of my `hg config` output (removed all the templates, irrelevant aliases, merge-tools, etc. stuff): commands.status.relative=True diff.git=yes experimental.bundle2.pushback=True experimental.changegroup3=True experimental.updatecheck=noconflict experimental.bundle2-exp=True experimental.evolution=['all'] extensions.backups= extensions.morestatus= extensions.chistedit= extensions.google_hgext= extensions.narrowhg= extensions.remotefilelog= extensions.evolve= extensions.patience=~/src/hg/extensions/patience/patience.py extensions.blackbox= extensions.hgext.multidiff=~/.hgext/multidiff.py extensions.hgext.pdb_interrupt=~/.hgext/pdb_interrupt.py extensions.extdiff= extensions.histedit= extensions.patchbomb= extensions.absorb= extensions.graphlog= extensions.progress= extensions.rebase= extensions.record= extensions.shelve= extensions.transplant= extensions.nointerrupt=! hooks.preupdate.readonlysymlink= hooks.update.readonlysymlink= hooks.pretxnchangegroup.fig_requirement= hooks.update.prefetch= hooks.commit.prefetch= morestatus.show=True pager.pager=less -FrX paths.default=ssh://h...@bitbucket.org/facebook/hg-experimental paths.default-push=ssh://h...@bitbucket.org/spectral54/hg-experimental phases.publish=false trusted.users=root ui.supportcontact=http://go/fig-bug ui.color=auto ui.rollback=False ui.interface=curses ui.editor=vim -X ui.username=Kyle Lippincottui.merge=vim_1pane ui.mergemarkers=detailed ui.diff=vimdiff ui.ssh=ssh -C ui.ignore=~/.hgignore ui.paginate=False I have a bitbucket fork at http://bitbucket.org/spectral54/hg-experimental (forked from http://bitbucket.org/facebook/hg-experimental). This fork, as well as the upstream repo, has evolve enabled. I have the following graph: @ 3551:fe313cd2 spectral tip @ | basepack: do not keep fd open | o 3549:f23f3939 spectral | | basepack: close files after mmap if we never need to remap | o 3548:22cb1670 spectral |/ basepack: don't re-mmap if re-reading the same data makes pagedin > MAXPAGEDIN o 3540:6a9de6c2 quark : cdatapack: do not keep fd open I wanted to push 3551 as a new head, so I did `hg push -f`, realized it would push the "lots of other stuff" as well, and hit Ctrl-C. I've trimmed the output a bit, since I wrote an extension that dumps me into pdb if I hit Ctrl-C, and then I hit Ctrl-D to exit pdb. I don't think this is relevant, but it might be. With that removed from the output, the output looks like: ≻ hg push -f pushing to ssh://h...@bitbucket.org/spectral54/hg-experimental searching for changes remote: adding changesets remote: adding manifests remote: adding file changes ^C Alright, now I wanted to do `hg push -f -r .`: ≻ hg push -f -r . pushing to ssh://h...@bitbucket.org/spectral54/hg-experimental searching for changes remote: abort: abandoned transaction found! remote: (run 'hg recover' to clean up transaction) abort: stream ended unexpectedly (got 0 bytes, expected 4) ≻ hg recover no interrupted transaction available ... and this persisted until someone from bitbucket was able to go clean up the transaction on the remote side. I don't think it should be
D1224: merge: cache unknown dir checks (issue5716)
sid0 added a comment. Could you make this a class with unknowndircache and missingdircache being private members? How much do you think writing some of this code in native code (e.g. Rust) would help? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1224 To: mbthomas, #hg-reviewers Cc: sid0, krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1224: merge: cache unknown dir checks (issue5716)
mbthomas added a comment. There is still some cost to doing the check, so it's not a complete reversal of issue5716, but it helps a lot. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1224 To: mbthomas, #hg-reviewers Cc: krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1226: merge: check created file dirs for path conflicts only once
mbthomas created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY In large repositories, updates involving the creation of many files check the same directories repeatedly. Move these checks out to a separate loop to avoid repeated checks that hit the filesystem. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1226 AFFECTED FILES mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -914,34 +914,21 @@ # can't be updated to cleanly. invalidconflicts = set() +# The set of directories that contain files that are being created. +createdfiledirs = set() + # The set of files deleted by all the actions. deletedfiles = set() for f, (m, args, msg) in actions.items(): if m in ('c', 'dc', 'm', 'cm'): # This action may create a new local file. +createdfiledirs.update(util.finddirs(f)) if mf.hasdir(f): # The file aliases a local directory. This might be ok if all # the files in the local directory are being deleted. This # will be checked once we know what all the deleted files are. remoteconflicts.add(f) -for p in util.finddirs(f): -if p in mf: -if p in mctx: -# The file is in a directory which aliases both a local -# and a remote file. This is an internal inconsistency -# within the remote manifest. -invalidconflicts.add(p) -else: -# The file is in a directory which aliases a local file. -# We will need to rename the local file. -localconflicts.add(p) -if p in actions and actions[p][0] in ('c', 'dc', 'm', 'cm'): -# The file is in a directory which aliases a remote file. -# This is an internal inconsistency within the remote -# manifest. -invalidconflicts.add(p) - # Track the names of all deleted files. if m == 'r': deletedfiles.add(f) @@ -953,6 +940,24 @@ f2, flags = args deletedfiles.add(f2) +# Check all directories that contain created files for path conflicts. +for p in createdfiledirs: +if p in mf: +if p in mctx: +# A file is in a directory which aliases both a local +# and a remote file. This is an internal inconsistency +# within the remote manifest. +invalidconflicts.add(p) +else: +# A file is in a directory which aliases a local file. +# We will need to rename the local file. +localconflicts.add(p) +if p in actions and actions[p][0] in ('c', 'dc', 'm', 'cm'): +# The file is in a directory which aliases a remote file. +# This is an internal inconsistency within the remote +# manifest. +invalidconflicts.add(p) + # Rename all local conflicting files that have not been deleted. for p in localconflicts: if p not in deletedfiles: To: mbthomas, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Deploying registrar configs in a BC safe way
I've been trying to update our extensions to support the new registrar class, and one thing I've noticed is that it's not really possible to have code that works with old versions of mercurial and new versions of mercurial at the same time, without having devel warnings. I can easily stub out the registration logic if the registrar module doesn't exist, but I can't leave the default values on the actual config accessor lines, which old mercurial versions would need. For now I'm just updating our extensions to only work with new mercurial, but if someone tries to use them with an older version it will cause subtle failures as the default configs will be different. I tried to think of some way to fix this, like by leaving the defaults on the config access line, but ignoring it somehow, but that sounds funky. Thoughts on how to fix this? ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1224: merge: cache unknown dir checks
krbullock added a comment. Code LGTM, but I haven't done any performance testing on this. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1224 To: mbthomas, #hg-reviewers Cc: krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1224: merge: cache unknown dir checks
krbullock added a comment. If this mitigates or fixes issue5716, please mention it in the summary line. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1224 To: mbthomas, #hg-reviewers Cc: krbullock, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1224: merge: cache unknown dir checks
mbthomas created this revision. Herald added a subscriber: mercurial-devel. Herald added a reviewer: hg-reviewers. REVISION SUMMARY As mentioned in https://phab.mercurial-scm.org/D1222, the recent pathconflicts change regresses update performance in large repositories when many files are being updated. To mitigate this, we introduce two caches of directories that have already found to be either: - unknown directories, but which are not aliased by files and so don't need to be checked if they are files again; and - missing directores, which cannot cause path conflicts, and cannot contain a file that causes a path conflict. When checking the paths of a file, testing against this caches means we can skip tests that involve touching the filesystem. REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1224 AFFECTED FILES mercurial/merge.py CHANGE DETAILS diff --git a/mercurial/merge.py b/mercurial/merge.py --- a/mercurial/merge.py +++ b/mercurial/merge.py @@ -653,23 +653,40 @@ and repo.dirstate.normalize(f) not in repo.dirstate and mctx[f2].cmp(wctx[f])) -def _checkunknowndirs(repo, f): +def _checkunknowndirs(repo, f, unknowndircache, missingdircache): """ Look for any unknown files or directories that may have a path conflict with a file. If any path prefix of the file exists as a file or link, then it conflicts. If the file itself is a directory that contains any file that is not tracked, then it conflicts. +`unknowndircache` is a set of paths known to be good. This prevents +repeated checking of dirs. It will be updated with any new dirs that +are checked and found to be safe. + +`missingdircache` is a set of paths that are known to be absent. This +prevents repeated checking of subdirectories that are known not to exist. +It will be updated with any new dirs that are checked and found to be +absent. + Returns the shortest path at which a conflict occurs, or None if there is no conflict. """ # Check for path prefixes that exist as unknown files. for p in reversed(list(util.finddirs(f))): -if (repo.wvfs.audit.check(p) -and repo.wvfs.isfileorlink(p) -and repo.dirstate.normalize(p) not in repo.dirstate): -return p +if p in missingdircache: +return +if p in unknowndircache: +continue +if repo.wvfs.audit.check(p): +if (repo.wvfs.isfileorlink(p) +and repo.dirstate.normalize(p) not in repo.dirstate): +return p +if not repo.wvfs.lexists(p): +missingdircache.add(p) +return +unknowndircache.add(p) # Check if the file conflicts with a directory containing unknown files. if repo.wvfs.audit.check(f) and repo.wvfs.isdir(f): @@ -700,12 +717,15 @@ elif config == 'warn': warnconflicts.update(conflicts) +unknowndircache = set() +missingdircache = set() for f, (m, args, msg) in actions.iteritems(): if m in ('c', 'dc'): if _checkunknownfile(repo, wctx, mctx, f): fileconflicts.add(f) elif f not in wctx: -path = _checkunknowndirs(repo, f) +path = _checkunknowndirs(repo, f, + unknowndircache, missingdircache) if path is not None: pathconflicts.add(path) elif m == 'dg': To: mbthomas, #hg-reviewers Cc: mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
D1222: merge: add a config option to disable path conflict checking
lothiraldan added a comment. The `debug` section doesn't seem to exists, could we use 'experimental' instead while we fix the performance regression? REPOSITORY rHG Mercurial REVISION DETAIL https://phab.mercurial-scm.org/D1222 To: sid0, #hg-reviewers Cc: lothiraldan, mercurial-devel ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Re: [PATCH] update: in the description update() in merge.py, mention the long options explicitly
Oh, thanks again. I did not know those checks existed. I'll use them in the future, so much better. On 10/24/2017 05:33 AM, Kevin Bullock wrote: On Oct 23, 2017, at 22:26, Kevin Bullockwrote: On Oct 23, 2017, at 17:03, muxator wrote: On 10/23/2017 11:56 PM, Kevin Bullock wrote: On Oct 23, 2017, at 16:07, muxator via Mercurial-devel wrote: # HG changeset patch # User muxator # Date 1507152154 -7200 # Wed Oct 04 23:22:34 2017 +0200 # Branch stable # Node ID 83a8eaeba37151821781becdf285501ebf065695 # Parent 780d13a58b332b3d18595af698eed1190fbe971e update: in the description update() in merge.py, mention the long options explicitly The short options "-c" and "-C" may be confusing for a novice reading the documentation. Let's try to be more explicit, also mentioning the equivalent long options ("--check" and "--clean") in the comments. This looks good, but our usual style in help is to say: -c/--check and -C/--clean instead of having the long options in parentheses. Okay if I update that in-flight? no problem at all! Fixed in flight, re-wrapped, and queued, thanks. I also reworded the summary line to be shorter -- check-commit says hi. For future patches please consider running at least test-check-*.t before sending. pacem in terris / мир / शान्ति / سَلاَم / 平和 Kevin R. Bullock ___ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel