diff mercurial/revlog.py @ 49012:5b65721a75eb

revlog: recommit 49fd21f32695 with a fix for issue6528 `filelog.size` currently special cases two forms of metadata encoding: - copy data via the parent order as flag bit - censor data by peaking into the raw delta All other forms of metadata encoding including the empty metadata block are mishandled. In `basefilectx.cmp` the empty metadata block is explicitly checked to compensate for this. Restore 49fd21f32695, but disable it for filelog, so that the original flag bit use contines to work. Document all this mess for now in preparation of a proper rework. Differential Revision: https://phab.mercurial-scm.org/D11203
author Joerg Sonnenberger <joerg@bec.de>
date Tue, 20 Jul 2021 15:07:10 +0200
parents 642e31cb55f0
children 2bcf5e14bb7e
line wrap: on
line diff
--- a/mercurial/revlog.py	Fri Mar 18 12:23:47 2022 -0700
+++ b/mercurial/revlog.py	Tue Jul 20 15:07:10 2021 +0200
@@ -298,6 +298,7 @@
         persistentnodemap=False,
         concurrencychecker=None,
         trypending=False,
+        canonical_parent_order=True,
     ):
         """
         create a revlog object
@@ -373,6 +374,13 @@
 
         self._concurrencychecker = concurrencychecker
 
+        # parent order is supposed to be semantically irrelevant, so we
+        # normally resort parents to ensure that the first parent is non-null,
+        # if there is a non-null parent at all.
+        # filelog abuses the parent order as flag to mark some instances of
+        # meta-encoded files, so allow it to disable this behavior.
+        self.canonical_parent_order = canonical_parent_order
+
     def _init_opts(self):
         """process options (from above/config) to setup associated default revlog mode
 
@@ -898,7 +906,10 @@
                 raise error.WdirUnsupported
             raise
 
-        return entry[5], entry[6]
+        if self.canonical_parent_order and entry[5] == nullrev:
+            return entry[6], entry[5]
+        else:
+            return entry[5], entry[6]
 
     # fast parentrevs(rev) where rev isn't filtered
     _uncheckedparentrevs = parentrevs
@@ -919,7 +930,11 @@
     def parents(self, node):
         i = self.index
         d = i[self.rev(node)]
-        return i[d[5]][7], i[d[6]][7]  # map revisions to nodes inline
+        # inline node() to avoid function call overhead
+        if self.canonical_parent_order and d[5] == self.nullid:
+            return i[d[6]][7], i[d[5]][7]
+        else:
+            return i[d[5]][7], i[d[6]][7]
 
     def chainlen(self, rev):
         return self._chaininfo(rev)[0]