# HG changeset patch # User Martin von Zweigbergk # Date 2018-02-01 18:29:24 # Node ID 5cfdf6137af87e52063a5a11a697bab805e4b03d # Parent 8a7140ec4c89500e18626a4dd72b4344f335f89c setdiscovery: don't call "heads" wire command when heads specified Our custom server has too many heads to announce (one per code review, plus a public head), but it still lets the user request one of them by doing hg pull -r After the client has resolved the expression to a set of nodeids by calling the "lookup" wire command, it will start the discovery phase. Before this patch, that doesn't take the requested heads into account and unconditionally calls the server's "heads" command to find all its heads. One consequence of that the "all remote heads known locally" case triggers if the client already had the public head and the user will see a "no changes found" message that's unrelated to the head they requested. That message confused me for a while. More imporantly, it also means that pullop.cgresult incorrectly (given our arguably misbehaving server) gets set to 0 (no changesets added), which confused some of our extensions. This patch makes it so the client skips the "heads" command if the user requested specific revisions. Since the "heads" command is normally batched with the first "known" command and calculating the list of heads is probably cheap, I don't expect much improvement in speed from this. Differential Revision: https://phab.mercurial-scm.org/D1962 diff --git a/mercurial/discovery.py b/mercurial/discovery.py --- a/mercurial/discovery.py +++ b/mercurial/discovery.py @@ -62,7 +62,7 @@ def findcommonincoming(repo, remote, hea if allknown: return (heads, False, heads) - res = setdiscovery.findcommonheads(repo.ui, repo, remote, + res = setdiscovery.findcommonheads(repo.ui, repo, remote, heads, abortwhenunrelated=not force, ancestorsof=ancestorsof) common, anyinc, srvheads = res diff --git a/mercurial/setdiscovery.py b/mercurial/setdiscovery.py --- a/mercurial/setdiscovery.py +++ b/mercurial/setdiscovery.py @@ -130,7 +130,7 @@ def _limitsample(sample, desiredlen): sample = set(random.sample(sample, desiredlen)) return sample -def findcommonheads(ui, local, remote, +def findcommonheads(ui, local, remote, heads=None, initialsamplesize=100, fullsamplesize=200, abortwhenunrelated=True, @@ -155,11 +155,15 @@ def findcommonheads(ui, local, remote, sample = _limitsample(ownheads, initialsamplesize) # indices between sample and externalized version must match sample = list(sample) - batch = remote.iterbatch() - batch.heads() - batch.known(dag.externalizeall(sample)) - batch.submit() - srvheadhashes, yesno = batch.results() + if heads: + srvheadhashes = heads + yesno = remote.known(dag.externalizeall(sample)) + else: + batch = remote.iterbatch() + batch.heads() + batch.known(dag.externalizeall(sample)) + batch.submit() + srvheadhashes, yesno = batch.results() if cl.tip() == nullid: if srvheadhashes != [nullid]: