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.
--- 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