# HG changeset patch # User Pierre-Yves David # Date 1610755323 -3600 # Node ID 6ee9bd69ff7ffef66ae0bf3554c45841b42ddd51 # Parent 2ef575c62f10c8334351399f88b9498acc10916a discovery: add a devel.discovery.exchange-heads Currently all discovery start with testing local and remote heads. For analysis purpose we make it possible to disable that initial "handshake" and start discovery with the whole repository as undecided. Differential Revision: https://phab.mercurial-scm.org/D9801 diff -r 2ef575c62f10 -r 6ee9bd69ff7f mercurial/configitems.py --- a/mercurial/configitems.py Sun Jan 17 02:48:15 2021 +0100 +++ b/mercurial/configitems.py Sat Jan 16 01:02:03 2021 +0100 @@ -702,6 +702,13 @@ b'debug.peer-request', default=False, ) +# If discovery.exchange-heads is False, the discovery will not start with +# remote head fetching and local head querying. +coreconfigitem( + b'devel', + b'discovery.exchange-heads', + default=True, +) # If discovery.grow-sample is False, the sample size used in set discovery will # not be increased through the process coreconfigitem( diff -r 2ef575c62f10 -r 6ee9bd69ff7f mercurial/setdiscovery.py --- a/mercurial/setdiscovery.py Sun Jan 17 02:48:15 2021 +0100 +++ b/mercurial/setdiscovery.py Sat Jan 16 01:02:03 2021 +0100 @@ -314,6 +314,8 @@ else: ownheads = [rev for rev in cl.headrevs() if rev != nullrev] + initial_head_exchange = ui.configbool(b'devel', b'discovery.exchange-heads') + # We also ask remote about all the local heads. That set can be arbitrarily # large, so we used to limit it size to `initialsamplesize`. We no longer # do as it proved counter productive. The skipped heads could lead to a @@ -365,33 +367,39 @@ # graph (with many heads) attached to, but very independant to a the # "simple" graph on the server. This is a fairly usual case and have # not been met in the wild so far. - if remote.limitedarguments: - sample = _limitsample(ownheads, initialsamplesize) - # indices between sample and externalized version must match - sample = list(sample) - else: - sample = ownheads + if initial_head_exchange: + if remote.limitedarguments: + sample = _limitsample(ownheads, initialsamplesize) + # indices between sample and externalized version must match + sample = list(sample) + else: + sample = ownheads - ui.debug(b"query 1; heads\n") - roundtrips += 1 - with remote.commandexecutor() as e: - fheads = e.callcommand(b'heads', {}) - fknown = e.callcommand( - b'known', - { - b'nodes': [clnode(r) for r in sample], - }, - ) + ui.debug(b"query 1; heads\n") + roundtrips += 1 + with remote.commandexecutor() as e: + fheads = e.callcommand(b'heads', {}) + fknown = e.callcommand( + b'known', + { + b'nodes': [clnode(r) for r in sample], + }, + ) + + srvheadhashes, yesno = fheads.result(), fknown.result() - srvheadhashes, yesno = fheads.result(), fknown.result() - - if audit is not None: - audit[b'total-roundtrips'] = 1 + if audit is not None: + audit[b'total-roundtrips'] = 1 - if cl.tip() == nullid: - if srvheadhashes != [nullid]: - return [nullid], True, srvheadhashes - return [nullid], False, [] + if cl.tip() == nullid: + if srvheadhashes != [nullid]: + return [nullid], True, srvheadhashes + return [nullid], False, [] + else: + # we still need the remote head for the function return + with remote.commandexecutor() as e: + fheads = e.callcommand(b'heads', {}) + srvheadhashes = fheads.result() # start actual discovery (we note this before the next "if" for # compatibility reasons) @@ -408,15 +416,16 @@ except error.LookupError: continue - # early exit if we know all the specified remote heads already - if len(knownsrvheads) == len(srvheadhashes): - ui.debug(b"all remote heads known locally\n") - return srvheadhashes, False, srvheadhashes + if initial_head_exchange: + # early exit if we know all the specified remote heads already + if len(knownsrvheads) == len(srvheadhashes): + ui.debug(b"all remote heads known locally\n") + return srvheadhashes, False, srvheadhashes - if len(sample) == len(ownheads) and all(yesno): - ui.note(_(b"all local changesets known remotely\n")) - ownheadhashes = [clnode(r) for r in ownheads] - return ownheadhashes, True, srvheadhashes + if len(sample) == len(ownheads) and all(yesno): + ui.note(_(b"all local changesets known remotely\n")) + ownheadhashes = [clnode(r) for r in ownheads] + return ownheadhashes, True, srvheadhashes # full blown discovery @@ -429,12 +438,13 @@ disco = partialdiscovery( local, ownheads, hard_limit_sample, randomize=randomize ) - # treat remote heads (and maybe own heads) as a first implicit sample - # response - disco.addcommons(knownsrvheads) - disco.addinfo(zip(sample, yesno)) + if initial_head_exchange: + # treat remote heads (and maybe own heads) as a first implicit sample + # response + disco.addcommons(knownsrvheads) + disco.addinfo(zip(sample, yesno)) - full = False + full = not initial_head_exchange progress = ui.makeprogress(_(b'searching'), unit=_(b'queries')) while not disco.iscomplete(): diff -r 2ef575c62f10 -r 6ee9bd69ff7f tests/test-setdiscovery.t --- a/tests/test-setdiscovery.t Sun Jan 17 02:48:15 2021 +0100 +++ b/tests/test-setdiscovery.t Sat Jan 16 01:02:03 2021 +0100 @@ -1412,23 +1412,22 @@ missing: 1040 common heads: 3ee37d65064a - $ hg -R a debugdiscovery b --debug --config devel.discovery.randomize=false --config devel.discovery.grow-sample.rate=1.01 + $ hg -R a debugdiscovery b --debug --config devel.discovery.exchange-heads=false --config devel.discovery.randomize=false --config devel.discovery.grow-sample.rate=1.01 comparing with b - query 1; heads searching for changes - taking quick initial sample - query 2; still undecided: 1080, sample size is: 100 sampling from both directions - query 3; still undecided: 980, sample size is: 200 + query 1; still undecided: 1340, sample size is: 200 + sampling from both directions + query 2; still undecided: 795, sample size is: 202 sampling from both directions - query 4; still undecided: 497, sample size is: 202 + query 3; still undecided: 525, sample size is: 204 sampling from both directions - query 5; still undecided: 294, sample size is: 204 + query 4; still undecided: 252, sample size is: 206 sampling from both directions - query 6; still undecided: 90, sample size is: 90 - 6 total queries in *s (glob) + query 5; still undecided: 44, sample size is: 44 + 5 total queries in *s (glob) elapsed time: * seconds (glob) - round-trips: 6 + round-trips: 5 heads summary: total common heads: 1 also local heads: 0