push: extract new common set computation from phase synchronisation
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Thu, 30 Jan 2014 23:12:03 -0800
changeset 20468 7d0bbb6dd730
parent 20467 ef880ced6d07
child 20469 6b4c789d618d
push: extract new common set computation from phase synchronisation Now that every necessary information is held in the `pushoperation` object, we can extract the new common set computation to it's own function. This changeset is pure code movement only.
mercurial/exchange.py
--- a/mercurial/exchange.py	Thu Jan 30 23:16:43 2014 -0800
+++ b/mercurial/exchange.py	Thu Jan 30 23:12:03 2014 -0800
@@ -104,6 +104,7 @@
             _pushdiscovery(pushop)
             if _pushcheckoutgoing(pushop):
                 _pushchangeset(pushop)
+            _pushcomputecommonheads(pushop)
             _pushsyncphase(pushop)
             _pushobsolete(pushop)
         finally:
@@ -207,9 +208,44 @@
         pushop.ret = pushop.remote.addchangegroup(cg, 'push',
                                                               pushop.repo.url())
 
+def _pushcomputecommonheads(pushop):
+    unfi = pushop.repo.unfiltered()
+    if pushop.ret:
+        # push succeed, synchronize target of the push
+        cheads = pushop.outgoing.missingheads
+    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)
+    pushop.commonheads = cheads
+
 def _pushsyncphase(pushop):
     """synchronise phase information locally and remotly"""
     unfi = pushop.repo.unfiltered()
+    cheads = pushop.commonheads
     if pushop.ret:
         # push succeed, synchronize target of the push
         cheads = pushop.outgoing.missingheads