push: put obsmarkers in the same bundle2 than changeset
authorPierre-Yves David <pierre-yves.david@fb.com>
Fri, 25 Jul 2014 16:54:08 +0200
changeset 1006 deba3a063c63
parent 1005 4fe159fdfc4c
child 1007 1d8ba8244001
push: put obsmarkers in the same bundle2 than changeset When client is Mercurial 3.1 and server have proper evolve version and both side have bundle2 enabled, we'll includes a part containing obsolescence markers. When obsmarkers are included to the main bundle2 push, they will failed to be pushed if the changeset failed to be pushed (and reciprocally).
README
hgext/evolve.py
--- a/README	Mon Jul 28 00:08:06 2014 +0200
+++ b/README	Fri Jul 25 16:54:08 2014 +0200
@@ -62,6 +62,8 @@
 - amend: add -D/--current-date option
 - amend: add -U/--current-user option
 - evolve: add a --tool option
+- push obsmarkers in the same transaction than changesets (when using hg >= 3.1
+  and bundle2-exp is enabled)
 
 4.0.0 -- 2014-06-03
 
--- a/hgext/evolve.py	Mon Jul 28 00:08:06 2014 +0200
+++ b/hgext/evolve.py	Fri Jul 25 16:54:08 2014 +0200
@@ -2318,7 +2318,36 @@
             yield d
             d = self.read(4096)
 
+bundle2partsgenerators = getattr(exchange, 'bundle2partsgenerators', None)
 
+if bundle2partsgenerators is not None:
+    def _pushb2obsmarker(pushop, bundler):
+        """adds obsmarker to the main bundle2 push"""
+        repo = pushop.repo
+        remote = pushop.remote
+        if ('obsmarkers' not in pushop.stepsdone
+            and (obsolete._enabled and repo.obsstore and
+                 'obsolete' in remote.listkeys('namespaces'))
+            and remote.capable('_evoext_b2x_obsmarkers_0')):
+            #
+            pushop.stepsdone.add('obsmarkers')
+            markers = _obsmarkersdiscovery(pushop)
+            if not markers:
+                repo.ui.status("OBSEXC: no marker to push\n")
+                repo.ui.status("OBSEXC: DONE\n")
+                return
+            obsdata = pushobsmarkerStringIO()
+            _encodemarkersstream(obsdata, markers)
+            obsdata.seek(0)
+            obsdata.ui = repo.ui
+            repo.ui.status("OBSEXC: pushing %i markers (%i bytes)\n"
+                           % (len(markers), len(obsdata.getvalue())))
+            bundler.newpart('EVOLVE:B2X:OBSMARKERV1', data=obsdata)
+            def callback(op):
+                repo.ui.progress('OBSEXC', None)
+                repo.ui.status("OBSEXC: DONE\n")
+            return callback
+    bundle2partsgenerators.append(_pushb2obsmarker)
 
 
 def _obsmarkersdiscovery(pushop):
@@ -2334,8 +2363,13 @@
     cl = unfi.changelog
     commonheads = pushop.commonheads
     if commonheads is None:
-        # ctx not pushed yet, we try to be in the same bundle2
-        commonheads = pushop.outgoing.missingheads
+        if pushop.revs is None:
+            commonheads = pushop.outgoing.commonheads
+            sch = set(commonheads)
+            commonheads.extend(h for h in pushop.outgoing.missingheads
+                               if h not in sch)
+        else:
+            commonheads = pushop.outgoing.missingheads
     if (obsolete._enabled and repo.obsstore and
         'obsolete' in remote.listkeys('namespaces')):
         repo.ui.status("OBSEXC: computing relevant nodes\n")
@@ -2344,7 +2378,7 @@
         if remote.capable('_evoext_obshash_0'):
             repo.ui.status("OBSEXC: looking for common markers in %i nodes\n"
                            % len(revs))
-            common = findcommonobsmarkers(pushop.ui, repo, remote, revs)
+            common = findcommonobsmarkers(pushop.ui, unfi, remote, revs)
             revs = list(unfi.revs('%ld - (::%ln)', revs, common))
         nodes = [cl.node(r) for r in revs]
         if nodes: