changeset 50374:05d429fe84ed stable

revlog: fix a bug in revlog splitting Specifically, if the .i.s files are not added to the transaction, then a follow-up modification of such a file records it into transaction as non-empty, which is incorrect.
author Arseniy Alekseyev <aalekseyev@janestreet.com>
date Mon, 05 Jun 2023 11:07:08 +0200
parents 553865308b15
children bf7404f2e22d
files mercurial/transaction.py tests/test-transaction-rollback-on-revlog-split.t
diffstat 2 files changed, 21 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/transaction.py	Thu Jun 01 22:32:21 2023 +0100
+++ b/mercurial/transaction.py	Mon Jun 05 11:07:08 2023 +0200
@@ -290,6 +290,8 @@
         self._backupjournal = b"%s.backupfiles" % self._journal
         self._backupsfile = opener.open(self._backupjournal, b'w')
         self._backupsfile.write(b'%d\n' % version)
+        # the set of temporary files
+        self._tmp_files = set()
 
         if createmode is not None:
             opener.chmod(self._journal, createmode & 0o666)
@@ -354,6 +356,7 @@
             file in self._newfiles
             or file in self._offsetmap
             or file in self._backupmap
+            or file in self._tmp_files
         ):
             return
         if self._queue:
@@ -368,6 +371,7 @@
             file in self._newfiles
             or file in self._offsetmap
             or file in self._backupmap
+            or file in self._tmp_files
         ):
             return
         if offset:
@@ -439,6 +443,7 @@
         Such files will be deleted when the transaction exits (on both
         failure and success).
         """
+        self._tmp_files.add(tmpfile)
         self._addbackupentry((location, b'', tmpfile, False))
 
     @active
--- a/tests/test-transaction-rollback-on-revlog-split.t	Thu Jun 01 22:32:21 2023 +0100
+++ b/tests/test-transaction-rollback-on-revlog-split.t	Mon Jun 05 11:07:08 2023 +0200
@@ -104,13 +104,17 @@
   >     dd if=/dev/zero of=$f bs=1k count=128 > /dev/null 2>&1
   > done
   $ hg commit -AqmD --traceback
+  $ for f in $files; do
+  >     dd if=/dev/zero of=$f bs=1k count=132 > /dev/null 2>&1
+  > done
+  $ hg commit -AqmD --traceback
 
 Reference size:
   $ f -s file
-  file: size=131072
+  file: size=135168
   $ f -s .hg/store/data/file*
-  .hg/store/data/file.d: size=132139
-  .hg/store/data/file.i: size=256
+  .hg/store/data/file.d: size=267307
+  .hg/store/data/file.i: size=320
 
   $ cd ..
 
@@ -157,10 +161,12 @@
 
 The inline revlog still exist, but a split version exist next to it
 
+  $ cat .hg/store/journal | tr '\0' ' ' | grep '\.s'
+  [1]
   $ f -s .hg/store/data/file*
-  .hg/store/data/file.d: size=132139
+  .hg/store/data/file.d: size=267307
   .hg/store/data/file.i: size=132395
-  .hg/store/data/file.i.s: size=256
+  .hg/store/data/file.i.s: size=320
 
 
 The first file.i entry should match the "Reference size" above.
@@ -237,9 +243,9 @@
 The inline revlog still exist, but a split version exist next to it
 
   $ f -s .hg/store/data/file*
-  .hg/store/data/file.d: size=132139
+  .hg/store/data/file.d: size=267307
   .hg/store/data/file.i: size=132395
-  .hg/store/data/file.i.s: size=256
+  .hg/store/data/file.i.s: size=320
 
   $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
   data/file.i 1174
@@ -302,8 +308,8 @@
 The inline revlog was over written on disk
 
   $ f -s .hg/store/data/file*
-  .hg/store/data/file.d: size=132139
-  .hg/store/data/file.i: size=256
+  .hg/store/data/file.d: size=267307
+  .hg/store/data/file.i: size=320
 
   $ cat .hg/store/journal | tr -s '\000' ' ' | grep data/file
   data/file.i 1174
@@ -434,7 +440,7 @@
   adding changesets
   adding manifests
   adding file changes
-  size=131072
+  size=135168
   transaction abort!
   rollback completed
   abort: pretxnclose.03-abort hook exited with status 1