diff --git a/mercurial/setdiscovery.py b/mercurial/setdiscovery.py --- a/mercurial/setdiscovery.py +++ b/mercurial/setdiscovery.py @@ -275,9 +275,63 @@ def findcommonheads(ui, local, remote, # early exit if we know all the specified remote heads already ui.debug("query 1; heads\n") roundtrips += 1 - sample = _limitsample(ownheads, initialsamplesize) - # indices between sample and externalized version must match - sample = list(sample) + # 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 + # large "undecided" set, slower to be clarified than if we asked the + # question for all heads right away. + # + # We are already fetching all server heads using the `heads` commands, + # sending a equivalent number of heads the other way should not have a + # significant impact. In addition, it is very likely that we are going to + # have to issue "known" request for an equivalent amount of revisions in + # order to decide if theses heads are common or missing. + # + # find a detailled analysis below. + # + # Case A: local and server both has few heads + # + # Ownheads is below initialsamplesize, limit would not have any effect. + # + # Case B: local has few heads and server has many + # + # Ownheads is below initialsamplesize, limit would not have any effect. + # + # Case C: local and server both has many heads + # + # We now transfert some more data, but not significantly more than is + # already transfered to carry the server heads. + # + # Case D: local has many heads, server has few + # + # D.1 local heads are mostly known remotely + # + # All the known head will have be part of a `known` request at some + # point for the discovery to finish. Sending them all earlier is + # actually helping. + # + # (This case is fairly unlikely, it requires the numerous heads to all + # be merged server side in only a few heads) + # + # D.2 local heads are mostly missing remotely + # + # To determine that the heads are missing, we'll have to issue `known` + # request for them or one of their ancestors. This amount of `known` + # request will likely be in the same order of magnitude than the amount + # of local heads. + # + # The only case where we can be more efficient using `known` request on + # ancestors are case were all the "missing" local heads are based on a + # few changeset, also "missing". This means we would have a "complex" + # 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 with remote.commandexecutor() as e: fheads = e.callcommand('heads', {}) diff --git a/tests/test-setdiscovery.t b/tests/test-setdiscovery.t --- a/tests/test-setdiscovery.t +++ b/tests/test-setdiscovery.t @@ -926,7 +926,7 @@ Both many new on top of long history: common heads: 7ead0cba2838 -One with >200 heads, which used to use up all of the sample: +One with >200 heads. We now switch to send them all in the initial roundtrip, but still do sampling for the later request. $ hg init manyheads $ cd manyheads @@ -974,20 +974,17 @@ One with >200 heads, which used to use u searching for changes taking quick initial sample searching: 2 queries - query 2; still undecided: 1240, sample size is: 100 + query 2; still undecided: 1080, sample size is: 100 sampling from both directions searching: 3 queries - query 3; still undecided: 1140, sample size is: 200 + query 3; still undecided: 980, sample size is: 200 sampling from both directions searching: 4 queries query 4; still undecided: \d+, sample size is: 200 (re) sampling from both directions searching: 5 queries - query 5; still undecided: \d+, sample size is: 200 (re) - sampling from both directions - searching: 6 queries - query 6; still undecided: \d+, sample size is: \d+ (re) - 6 total queries in *.????s (glob) + query 5; still undecided: 195, sample size is: 195 + 5 total queries in *.????s (glob) elapsed time: * seconds (glob) heads summary: total common heads: 1 @@ -1116,6 +1113,6 @@ fixed in 86c35b7ae300: $ hg -R r1 --config extensions.blackbox= blackbox --config blackbox.track= * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> serve --cmdserver chgunix * (glob) (chg !) * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* (glob) - * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> found 101 common and 1 unknown server heads, 2 roundtrips in *.????s (glob) + * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> found 101 common and 1 unknown server heads, 1 roundtrips in *.????s (glob) * @5d0b986a083e0d91f116de4691e2aaa54d5bbec0 (*)> -R r1 outgoing r2 *-T{rev} * --config *extensions.blackbox=* exited 0 after *.?? seconds (glob) $ cd ..