# HG changeset patch # User Pierre-Yves David # Date 2024-02-23 03:26:03 # Node ID e2dfa403452d9b88d21f8b3d5b9d23b362b9b67d # Parent e9304c39e07590fe1d85ce1fa399f08aeed398d0 debug: add a debug::unbundle command that simulate the unbundle from a push The code have different behavior when the unbundle comes from a push, so we introduce a command that can simulate such unbundle. For our copy of mozilla-try-2023-03-22, this make the unbundle jump from 2.5 seconds (with `hg unbundle`) to 15 seconds (with `hg debug::unbundle`). That 15 seconds timings is consistent with the issue seen in production. diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -7730,7 +7730,7 @@ def tip(ui, repo, **opts): _(b'[-u] FILE...'), helpcategory=command.CATEGORY_IMPORT_EXPORT, ) -def unbundle(ui, repo, fname1, *fnames, **opts): +def unbundle(ui, repo, fname1, *fnames, _unbundle_source=b'unbundle', **opts): """apply one or more bundle files Apply one or more bundle files generated by :hg:`bundle`. @@ -7758,7 +7758,11 @@ def unbundle(ui, repo, fname1, *fnames, txnname = b'unbundle\n%s' % urlutil.hidepassword(url) with repo.transaction(txnname) as tr: op = bundle2.applybundle( - repo, gen, tr, source=b'unbundle', url=url + repo, + gen, + tr, + source=_unbundle_source, # used by debug::unbundle + url=url, ) except error.BundleUnknownFeatureError as exc: raise error.Abort( diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -4077,6 +4077,30 @@ def debugupgraderepo(ui, repo, run=False @command( + b'debug::unbundle', + [ + ( + b'u', + b'update', + None, + _(b'update to new branch head if changesets were unbundled'), + ) + ], + _(b'[-u] FILE...'), + helpcategory=command.CATEGORY_IMPORT_EXPORT, +) +def debugunbundle(ui, repo, *args, **kwargs): + """same as `hg unbundle`, but pretent to come from a push + + This is useful to debug behavior and performance change in this case. + """ + from . import commands # avoid cycle + + unbundle = cmdutil.findcmd(b'unbundle', commands.table)[1][0] + return unbundle(ui, repo, *args, _unbundle_source=b'push', **kwargs) + + +@command( b'debugwalk', cmdutil.walkopts, _(b'[OPTION]... [FILE]...'), inferrepo=True ) def debugwalk(ui, repo, *pats, **opts): diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -82,6 +82,7 @@ Show debug commands if there are no othe debug-revlog-stats debug::stable-tail-sort debug::stable-tail-sort-leaps + debug::unbundle debugancestor debugantivirusrunning debugapplystreamclonebundle @@ -280,6 +281,7 @@ Show all commands + options debug-revlog-stats: changelog, manifest, filelogs, template debug::stable-tail-sort: template debug::stable-tail-sort-leaps: template, specific + debug::unbundle: update debugancestor: debugantivirusrunning: debugapplystreamclonebundle: diff --git a/tests/test-debugcommands.t b/tests/test-debugcommands.t --- a/tests/test-debugcommands.t +++ b/tests/test-debugcommands.t @@ -659,6 +659,19 @@ Test cache warming command .hg/cache/branch2-immutable .hg/cache/branch2-base +Test debug::unbundle + + $ hg bundle --exact --rev tip foo.hg + 1 changesets found + $ hg debug::unbundle foo.hg + adding changesets + adding manifests + adding file changes + added 0 changesets with 0 changes to 1 files (no-pure !) + 9 local changesets published (no-pure !) + 3 local changesets published (pure !) + (run 'hg update' to get a working copy) + Test debugcolor #if no-windows diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -1006,6 +1006,8 @@ Test list of internal help commands debug::stable-tail-sort-leaps display the leaps in the stable-tail sort of a node, one per line + debug::unbundle + same as 'hg unbundle', but pretent to come from a push debugancestor find the ancestor revision of two revisions in a given index debugantivirusrunning