revlog: fix a bug where transaction can be aborted partially stable
authorArseniy Alekseyev <aalekseyev@janestreet.com>
Thu, 20 Jan 2022 14:06:36 +0000
branchstable
changeset 48571 ccd9cb73125c
parent 48570 f38ae2d7390e
child 48580 f1898680d713
revlog: fix a bug where transaction can be aborted partially Fix a repo corruption bug caused by a partial transaction rollback. Differential Revision: https://phab.mercurial-scm.org/D12009
mercurial/revlog.py
tests/test-transaction-rollback-on-revlog-split.t
--- a/mercurial/revlog.py	Thu Jan 20 14:02:58 2022 +0000
+++ b/mercurial/revlog.py	Thu Jan 20 14:06:36 2022 +0000
@@ -2006,7 +2006,7 @@
             raise error.RevlogError(
                 _(b"%s not found in the transaction") % self._indexfile
             )
-        trindex = 0
+        trindex = None
         tr.add(self._datafile, 0)
 
         existing_handles = False
@@ -2029,10 +2029,17 @@
             with self._indexfp() as read_ifh:
                 for r in self:
                     new_dfh.write(self._getsegmentforrevs(r, r, df=read_ifh)[1])
-                    if troffset <= self.start(r) + r * self.index.entry_size:
+                    if (
+                        trindex is None
+                        and troffset
+                        <= self.start(r) + r * self.index.entry_size
+                    ):
                         trindex = r
                 new_dfh.flush()
 
+            if trindex is None:
+                trindex = 0
+
             with self.__index_new_fp() as fp:
                 self._format_flags &= ~FLAG_INLINE_DATA
                 self._inline = False
--- a/tests/test-transaction-rollback-on-revlog-split.t	Thu Jan 20 14:02:58 2022 +0000
+++ b/tests/test-transaction-rollback-on-revlog-split.t	Thu Jan 20 14:06:36 2022 +0000
@@ -63,7 +63,7 @@
   [80]
 #endif
   $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file | tail -1
-  data/file.i 192
+  data/file.i 128
 
 The first file.i entry should match the "Reference size" above.
 The first file.d entry is the temporary record during the split,
@@ -73,14 +73,14 @@
   $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
   data/file.i 1174
   data/file.d 0
-  data/file.d 1067
-  data/file.i 192
+  data/file.d 1046
+  data/file.i 128
   $ hg recover
   rolling back interrupted transaction
   (verify step skipped, run `hg verify` to check your repository content)
   $ f -s .hg/store/data/file*
-  .hg/store/data/file.d: size=1067
-  .hg/store/data/file.i: size=192
+  .hg/store/data/file.d: size=1046
+  .hg/store/data/file.i: size=128
   $ hg tip
   changeset:   1:cfa8d6e60429
   tag:         tip
@@ -90,23 +90,12 @@
   
   $ hg verify -q
    warning: revlog 'data/file.d' not in fncache!
-   file@?: rev 2 points to nonexistent changeset 2
-   (expected )
-   file@?: fa1120531cc1 not in manifests
-  2 warnings encountered!
+  1 warnings encountered!
   hint: run "hg debugrebuildfncache" to recover from corrupt fncache
-  2 integrity errors encountered!
-  [1]
   $ hg debugrebuildfncache --only-data
   adding data/file.d
   1 items added, 0 removed from fncache
   $ hg verify -q
-   file@?: rev 2 points to nonexistent changeset 2
-   (expected )
-   file@?: fa1120531cc1 not in manifests
-  1 warnings encountered!
-  2 integrity errors encountered!
-  [1]
   $ cd ..
 
 
@@ -134,13 +123,13 @@
   $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
   data/file.i 1174
   data/file.d 0
-  data/file.d 1067
+  data/file.d 1046
 
   $ hg recover
   rolling back interrupted transaction
   (verify step skipped, run `hg verify` to check your repository content)
   $ f -s .hg/store/data/file*
-  .hg/store/data/file.d: size=1067
+  .hg/store/data/file.d: size=1046
   .hg/store/data/file.i: size=1174
   $ hg tip
   changeset:   1:cfa8d6e60429
@@ -172,8 +161,8 @@
   abort: pretxnchangegroup hook exited with status 1
   [40]
   $ f -s .hg/store/data/file*
-  .hg/store/data/file.d: size=1067
-  .hg/store/data/file.i: size=192
+  .hg/store/data/file.d: size=1046
+  .hg/store/data/file.i: size=128
   $ hg tip
   changeset:   1:cfa8d6e60429
   tag:         tip
@@ -183,12 +172,7 @@
   
   $ hg verify -q
    warning: revlog 'data/file.d' not in fncache!
-   file@?: rev 2 points to nonexistent changeset 2
-   (expected )
-   file@?: fa1120531cc1 not in manifests
-  2 warnings encountered!
+  1 warnings encountered!
   hint: run "hg debugrebuildfncache" to recover from corrupt fncache
-  2 integrity errors encountered!
-  [1]
   $ cd ..