diff mercurial/bundlerepo.py @ 50200:197204dba8a2

bundlerepo: apply phase data stored in the bundle instead of assuming `draft` The phase information contained in the changegroup part and the explicit `phase-heads` part are now taken in account. Initial changes and test by Matt Harbison, code rework by Pierre-Yves David.
author Matt Harbison <matt_harbison@yahoo.com>, Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 23 Feb 2023 23:05:51 +0100
parents 21f876895dfe
children 149f09ffef46
line wrap: on
line diff
--- a/mercurial/bundlerepo.py	Thu Feb 23 19:07:58 2023 +0100
+++ b/mercurial/bundlerepo.py	Thu Feb 23 23:05:51 2023 +0100
@@ -302,7 +302,9 @@
 
             cgpart = None
             for part in bundle.iterparts(seekable=True):
-                if part.type == b'changegroup':
+                if part.type == b'phase-heads':
+                    self._handle_bundle2_phase_part(bundle, part)
+                elif part.type == b'changegroup':
                     if cgpart:
                         raise NotImplementedError(
                             b"can't process multiple changegroups"
@@ -346,6 +348,17 @@
     def _handle_bundle2_cg_part(self, bundle, part):
         assert part.type == b'changegroup'
         cgstream = part
+        targetphase = part.params.get(b'targetphase')
+        try:
+            targetphase = int(targetphase)
+        except TypeError:
+            pass
+        if targetphase is None:
+            targetphase = phases.draft
+        if targetphase not in phases.allphases:
+            m = _(b'unsupported targetphase: %d')
+            m %= targetphase
+            raise error.Abort(m)
         version = part.params.get(b'version', b'01')
         legalcgvers = changegroup.supportedincomingversions(self)
         if version not in legalcgvers:
@@ -360,10 +373,17 @@
         phases.retractboundary(
             self,
             None,
-            phases.draft,
+            targetphase,
             [ctx.node() for ctx in self[self.firstnewrev :]],
         )
 
+    def _handle_bundle2_phase_part(self, bundle, part):
+        assert part.type == b'phase-heads'
+
+        unfi = self.unfiltered()
+        headsbyphase = phases.binarydecode(part)
+        phases.updatephases(unfi, lambda: None, headsbyphase)
+
     def _writetempbundle(self, readfn, suffix, header=b''):
         """Write a temporary file to disk"""
         fdtemp, temp = self.vfs.mkstemp(prefix=b"hg-bundle-", suffix=suffix)