phase-shelve: read patch details from a (possibly internal) node in the repo
authorJason R. Coombs <jaraco@jaraco.com>
Thu, 28 Jul 2022 12:53:11 -0400
changeset 49426 24ffd13893cc
parent 49425 35c9f0bc2648
child 49427 c4417029e6c2
phase-shelve: read patch details from a (possibly internal) node in the repo
mercurial/shelve.py
--- a/mercurial/shelve.py	Mon Aug 08 13:40:08 2022 -0400
+++ b/mercurial/shelve.py	Thu Jul 28 12:53:11 2022 -0400
@@ -22,6 +22,7 @@
 """
 
 import collections
+import io
 import itertools
 import stat
 
@@ -183,6 +184,27 @@
     def open_patch(self, mode=b'rb'):
         return self.vfs(self.name + b'.patch', mode)
 
+    def patch_from_node(self, repo, node):
+        repo = repo.unfiltered()
+        match = _optimized_match(repo, node)
+        fp = io.BytesIO()
+        cmdutil.exportfile(
+            repo,
+            [node],
+            fp,
+            opts=mdiff.diffopts(git=True),
+            match=match,
+        )
+        fp.seek(0)
+        return fp
+
+    def load_patch(self, repo):
+        try:
+            # prefer node-based shelf
+            return self.patch_from_node(repo, self.readinfo()[b'node'])
+        except (FileNotFoundError, error.RepoLookupError):
+            return self.open_patch()
+
     def _backupfilename(self, backupvfs, filename):
         def gennames(base):
             yield base
@@ -674,7 +696,7 @@
         ui.write(age, label=b'shelve.age')
         ui.write(b' ' * (12 - len(age)))
         used += 12
-        with shelf_dir.get(name).open_patch() as fp:
+        with shelf_dir.get(name).load_patch(repo) as fp:
             while True:
                 line = fp.readline()
                 if not line: