push: extract fallback heads computation into pushop
Similar motivation to `futureheads`, we extract the computation into pushop
to make it available early to all possibly interested parties.
--- a/mercurial/exchange.py Tue Jul 01 17:20:31 2014 +0200
+++ b/mercurial/exchange.py Tue Jul 01 17:20:47 2014 +0200
@@ -85,6 +85,39 @@
"""future remote heads if the changeset push succeeds"""
return self.outgoing.missingheads
+ @util.propertycache
+ def fallbackheads(self):
+ """future remote heads if the changeset push fails"""
+ if self.revs is None:
+ # not target to push, all common are relevant
+ return self.outgoing.commonheads
+ unfi = self.repo.unfiltered()
+ # I want cheads = heads(::missingheads and ::commonheads)
+ # (missingheads is revs with secret changeset filtered out)
+ #
+ # This can be expressed as:
+ # cheads = ( (missingheads and ::commonheads)
+ # + (commonheads and ::missingheads))"
+ # )
+ #
+ # while trying to push we already computed the following:
+ # common = (::commonheads)
+ # missing = ((commonheads::missingheads) - commonheads)
+ #
+ # We can pick:
+ # * missingheads part of common (::commonheads)
+ common = set(self.outgoing.common)
+ nm = self.repo.changelog.nodemap
+ cheads = [node for node in self.revs if nm[node] in common]
+ # and
+ # * commonheads parents on missing
+ revset = unfi.set('%ln and parents(roots(%ln))',
+ self.outgoing.commonheads,
+ self.outgoing.missing)
+ cheads.extend(c.node() for c in revset)
+ return cheads
+
+
def push(repo, remote, force=False, revs=None, newbranch=False):
'''Push outgoing changesets (limited by revs) from a local
repository to remote. Return an integer:
@@ -313,36 +346,10 @@
pushop.ret = pushop.remote.addchangegroup(cg, 'push', pushop.repo.url())
def _pushcomputecommonheads(pushop):
- unfi = pushop.repo.unfiltered()
if pushop.ret:
cheads = pushop.futureheads
- elif pushop.revs is None:
- # All out push fails. synchronize all common
- cheads = pushop.outgoing.commonheads
else:
- # I want cheads = heads(::missingheads and ::commonheads)
- # (missingheads is revs with secret changeset filtered out)
- #
- # This can be expressed as:
- # cheads = ( (missingheads and ::commonheads)
- # + (commonheads and ::missingheads))"
- # )
- #
- # while trying to push we already computed the following:
- # common = (::commonheads)
- # missing = ((commonheads::missingheads) - commonheads)
- #
- # We can pick:
- # * missingheads part of common (::commonheads)
- common = set(pushop.outgoing.common)
- nm = pushop.repo.changelog.nodemap
- cheads = [node for node in pushop.revs if nm[node] in common]
- # and
- # * commonheads parents on missing
- revset = unfi.set('%ln and parents(roots(%ln))',
- pushop.outgoing.commonheads,
- pushop.outgoing.missing)
- cheads.extend(c.node() for c in revset)
+ cheads = pushop.fallbackheads
pushop.commonheads = cheads
def _pushsyncphase(pushop):