diff -r a5de21c9e370 -r a86d21e70b2b mercurial/exchangev2.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mercurial/exchangev2.py Wed Sep 12 09:58:23 2018 -0700 @@ -0,0 +1,55 @@ +# exchangev2.py - repository exchange for wire protocol version 2 +# +# Copyright 2018 Gregory Szorc +# +# This software may be used and distributed according to the terms of the +# GNU General Public License version 2 or any later version. + +from __future__ import absolute_import + +from .node import ( + nullid, +) +from . import ( + setdiscovery, +) + +def pull(pullop): + """Pull using wire protocol version 2.""" + repo = pullop.repo + remote = pullop.remote + + # Figure out what needs to be fetched. + common, fetch, remoteheads = _pullchangesetdiscovery( + repo, remote, pullop.heads, abortwhenunrelated=pullop.force) + +def _pullchangesetdiscovery(repo, remote, heads, abortwhenunrelated=True): + """Determine which changesets need to be pulled.""" + + if heads: + knownnode = repo.changelog.hasnode + if all(knownnode(head) for head in heads): + return heads, False, heads + + # TODO wire protocol version 2 is capable of more efficient discovery + # than setdiscovery. Consider implementing something better. + common, fetch, remoteheads = setdiscovery.findcommonheads( + repo.ui, repo, remote, abortwhenunrelated=abortwhenunrelated) + + common = set(common) + remoteheads = set(remoteheads) + + # If a remote head is filtered locally, put it back in the common set. + # See the comment in exchange._pulldiscoverychangegroup() for more. + + if fetch and remoteheads: + nodemap = repo.unfiltered().changelog.nodemap + + common |= {head for head in remoteheads if head in nodemap} + + if set(remoteheads).issubset(common): + fetch = [] + + common.discard(nullid) + + return common, fetch, remoteheads