diff --git a/mercurial/dagutil.py b/mercurial/dagutil.py --- a/mercurial/dagutil.py +++ b/mercurial/dagutil.py @@ -154,8 +154,9 @@ class revlogbaseddag(basedag): class revlogdag(revlogbaseddag): '''dag interface to a revlog''' - def __init__(self, revlog): + def __init__(self, revlog, localsubset=None): revlogbaseddag.__init__(self, revlog, set(revlog)) + self._heads = localsubset def _getheads(self): return [r for r in self._revlog.headrevs() if r != nullrev] diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -734,6 +734,7 @@ def debugstate(ui, repo, **opts): [('', 'old', None, _('use old-style discovery')), ('', 'nonheads', None, _('use old-style discovery with non-heads included')), + ('', 'rev', [], 'restrict discovery to this set of revs'), ] + cmdutil.remoteopts, _('[-l REV] [-r REV] [-b BRANCH]... [OTHER]')) def debugdiscovery(ui, repo, remoteurl="default", **opts): @@ -747,11 +748,8 @@ def debugdiscovery(ui, repo, remoteurl=" # make sure tests are repeatable random.seed(12323) - def doit(localheads, remoteheads, remote=remote): + def doit(pushedrevs, remoteheads, remote=remote): if opts.get('old'): - if localheads: - raise error.Abort('cannot use localheads with old style ' - 'discovery') if not util.safehasattr(remote, 'branches'): # enable in-client legacy support remote = localrepo.locallegacypeer(remote.local()) @@ -765,7 +763,12 @@ def debugdiscovery(ui, repo, remoteurl=" all = dag.ancestorset(dag.internalizeall(common)) common = dag.externalizeall(dag.headsetofconnecteds(all)) else: - common, any, hds = setdiscovery.findcommonheads(ui, repo, remote) + nodes = None + if pushedrevs: + revs = scmutil.revrange(repo, pushedrevs) + nodes = [repo[r].node() for r in revs] + common, any, hds = setdiscovery.findcommonheads(ui, repo, remote, + ancestorsof=nodes) common = set(common) rheads = set(hds) lheads = set(repo.heads()) @@ -794,7 +797,7 @@ def debugdiscovery(ui, repo, remoteurl=" else: remoterevs, _checkout = hg.addbranchrevs(repo, remote, branches, opts.get('remote_head')) - localrevs = opts.get('local_head') + localrevs = opts.get('rev') doit(localrevs, remoterevs) @command('debugextensions', cmdutil.formatteropts, [], norepo=True) diff --git a/mercurial/setdiscovery.py b/mercurial/setdiscovery.py --- a/mercurial/setdiscovery.py +++ b/mercurial/setdiscovery.py @@ -133,7 +133,8 @@ def _limitsample(sample, desiredlen): def findcommonheads(ui, local, remote, initialsamplesize=100, fullsamplesize=200, - abortwhenunrelated=True): + abortwhenunrelated=True, + ancestorsof=None): '''Return a tuple (common, anyincoming, remoteheads) used to identify missing nodes from or in remote. ''' @@ -141,7 +142,11 @@ def findcommonheads(ui, local, remote, roundtrips = 0 cl = local.changelog - dag = dagutil.revlogdag(cl) + localsubset = None + if ancestorsof is not None: + rev = local.changelog.rev + localsubset = [rev(n) for n in ancestorsof] + dag = dagutil.revlogdag(cl, localsubset=localsubset) # early exit if we know all the specified remote heads already ui.debug("query 1; heads\n") diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -261,7 +261,7 @@ Show all commands + options debugdate: extended debugdeltachain: changelog, manifest, dir, template debugdirstate: nodates, datesort - debugdiscovery: old, nonheads, ssh, remotecmd, insecure + debugdiscovery: old, nonheads, rev, ssh, remotecmd, insecure debugextensions: template debugfileset: rev debugfsinfo: diff --git a/tests/test-setdiscovery.t b/tests/test-setdiscovery.t --- a/tests/test-setdiscovery.t +++ b/tests/test-setdiscovery.t @@ -16,11 +16,17 @@ Function to test discovery between two r > echo "% -- a -> b set" > hg -R a debugdiscovery b --verbose --debug --config progress.debug=true > echo + > echo "% -- a -> b set (tip only)" + > hg -R a debugdiscovery b --verbose --debug --config progress.debug=true --rev tip + > echo > echo "% -- b -> a tree" > hg -R b debugdiscovery a --verbose --old > echo > echo "% -- b -> a set" > hg -R b debugdiscovery a --verbose --debug --config progress.debug=true + > echo + > echo "% -- b -> a set (tip only)" + > hg -R b debugdiscovery a --verbose --debug --config progress.debug=true --rev tip > cd .. > } @@ -48,6 +54,13 @@ Small superset: common heads: 01241442b3c2 b5714e113bc0 local is subset + % -- a -> b set (tip only) + comparing with b + query 1; heads + searching for changes + all local heads known remotely + common heads: b5714e113bc0 + % -- b -> a tree comparing with a searching for changes @@ -62,6 +75,14 @@ Small superset: all remote heads known locally common heads: 01241442b3c2 b5714e113bc0 remote is subset + + % -- b -> a set (tip only) + comparing with a + query 1; heads + searching for changes + all remote heads known locally + common heads: 01241442b3c2 b5714e113bc0 + remote is subset Many new: @@ -86,6 +107,16 @@ Many new: 2 total queries in *.????s (glob) common heads: bebd167eb94d + % -- a -> b set (tip only) + comparing with b + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 31, sample size is: 31 + 2 total queries in *.????s (glob) + common heads: 66f7d451a68b + % -- b -> a tree comparing with a searching for changes @@ -101,6 +132,16 @@ Many new: query 2; still undecided: 2, sample size is: 2 2 total queries in *.????s (glob) common heads: bebd167eb94d + + % -- b -> a set (tip only) + comparing with a + query 1; heads + searching for changes + taking initial sample + searching: 2 queries + query 2; still undecided: 2, sample size is: 2 + 2 total queries in *.????s (glob) + common heads: bebd167eb94d Both sides many new with stub: @@ -124,6 +165,16 @@ Both sides many new with stub: 2 total queries in *.????s (glob) common heads: 2dc09a01254d + % -- a -> b set (tip only) + comparing with b + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 31, sample size is: 31 + 2 total queries in *.????s (glob) + common heads: 66f7d451a68b + % -- b -> a tree comparing with a searching for changes @@ -139,6 +190,16 @@ Both sides many new with stub: query 2; still undecided: 29, sample size is: 29 2 total queries in *.????s (glob) common heads: 2dc09a01254d + + % -- b -> a set (tip only) + comparing with a + query 1; heads + searching for changes + taking initial sample + searching: 2 queries + query 2; still undecided: 29, sample size is: 29 + 2 total queries in *.????s (glob) + common heads: 2dc09a01254d Both many new: @@ -163,6 +224,16 @@ Both many new: 2 total queries in *.????s (glob) common heads: 66f7d451a68b + % -- a -> b set (tip only) + comparing with b + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 31, sample size is: 31 + 2 total queries in *.????s (glob) + common heads: 66f7d451a68b + % -- b -> a tree comparing with a searching for changes @@ -178,6 +249,16 @@ Both many new: query 2; still undecided: 31, sample size is: 31 2 total queries in *.????s (glob) common heads: 66f7d451a68b + + % -- b -> a set (tip only) + comparing with a + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 31, sample size is: 31 + 2 total queries in *.????s (glob) + common heads: 66f7d451a68b Both many new skewed: @@ -202,6 +283,16 @@ Both many new skewed: 2 total queries in *.????s (glob) common heads: 66f7d451a68b + % -- a -> b set (tip only) + comparing with b + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 51, sample size is: 51 + 2 total queries in *.????s (glob) + common heads: 66f7d451a68b + % -- b -> a tree comparing with a searching for changes @@ -217,6 +308,16 @@ Both many new skewed: query 2; still undecided: 31, sample size is: 31 2 total queries in *.????s (glob) common heads: 66f7d451a68b + + % -- b -> a set (tip only) + comparing with a + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 31, sample size is: 31 + 2 total queries in *.????s (glob) + common heads: 66f7d451a68b Both many new on top of long history: @@ -244,6 +345,19 @@ Both many new on top of long history: 3 total queries in *.????s (glob) common heads: 7ead0cba2838 + % -- a -> b set (tip only) + comparing with b + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 1049, sample size is: 11 + sampling from both directions + searching: 3 queries + query 3; still undecided: 31, sample size is: 31 + 3 total queries in *.????s (glob) + common heads: 7ead0cba2838 + % -- b -> a tree comparing with a searching for changes @@ -262,6 +376,19 @@ Both many new on top of long history: query 3; still undecided: 15, sample size is: 15 3 total queries in *.????s (glob) common heads: 7ead0cba2838 + + % -- b -> a set (tip only) + comparing with a + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 1029, sample size is: 11 + sampling from both directions + searching: 3 queries + query 3; still undecided: 15, sample size is: 15 + 3 total queries in *.????s (glob) + common heads: 7ead0cba2838 One with >200 heads, which used to use up all of the sample: @@ -327,6 +454,18 @@ One with >200 heads, which used to use u query 6; still undecided: \d+, sample size is: \d+ (re) 6 total queries in *.????s (glob) common heads: 3ee37d65064a + $ hg -R a debugdiscovery b --debug --verbose --config progress.debug=true --rev tip + comparing with b + query 1; heads + searching for changes + taking quick initial sample + searching: 2 queries + query 2; still undecided: 303, sample size is: 9 + sampling from both directions + searching: 3 queries + query 3; still undecided: 3, sample size is: 3 + 3 total queries in *.????s (glob) + common heads: 3ee37d65064a Test actual protocol when pulling one new head in addition to common heads