Patchwork D10726: recover: only apply last journal record per file

login
register
mail settings
Submitter phabricator
Date May 18, 2021, 2:51 a.m.
Message ID <differential-rev-PHID-DREV-mpl4f7yx7rjebpfapbhy-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/49046/
State Superseded
Headers show

Comments

phabricator - May 18, 2021, 2:51 a.m.
joerg.sonnenberger created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  This got broken in 2019 when the size check was introduced. It is most
  noticable when dealing with transactions that involve an inline to
  non-inline revlog storage transaction. It wasn't seen as much at the
  time because the in-memory journal actually de-duplicated the entry
  implicity, but since 63edc384d3b7 <https://phab.mercurial-scm.org/rHG63edc384d3b7f497fba4c1797bab86eede583dca> the on-disk journal is used for
  rollback as well as recover.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10726

AFFECTED FILES
  mercurial/transaction.py
  tests/test-transaction-rollback-on-revlog-split.t

CHANGE DETAILS




To: joerg.sonnenberger, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

diff --git a/tests/test-transaction-rollback-on-revlog-split.t b/tests/test-transaction-rollback-on-revlog-split.t
--- a/tests/test-transaction-rollback-on-revlog-split.t
+++ b/tests/test-transaction-rollback-on-revlog-split.t
@@ -4,9 +4,9 @@ 
 Helper extension to intercept renames.
 
   $ cat > $TESTTMP/intercept_rename.py << EOF
-  > from mercurial.extensions import wrapfunction
-  > from mercurial.util import atomictempfile
-  > import os, sys
+  > import os
+  > import sys
+  > from mercurial import extensions, util
   > 
   > def extsetup(ui):
   >     def close(orig, *args, **kwargs):
@@ -14,7 +14,7 @@ 
   >         if path.endswith(b'/.hg/store/data/file.i'):
   >             os._exit(80)
   >         return orig(*args, **kwargs)
-  >     wrapfunction(atomictempfile, 'close', close)
+  >     extensions.wrapfunction(util.atomictempfile, 'close', close)
   > EOF
 
 
@@ -62,6 +62,28 @@ 
   data/file.d 0
   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=1046
+  .hg/store/data/file.i: size=128
+  $ hg tip
+  changeset:   1:3ce491143aec
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     _
+  
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+   warning: revlog 'data/file.d' not in fncache!
+  checked 2 changesets with 2 changes to 1 files
+  1 warnings encountered!
+  hint: run "hg debugrebuildfncache" to recover from corrupt fncache
   $ cd ..
 
 Now retry the same but intercept the rename of the index and check that
@@ -83,4 +105,24 @@ 
   data/file.i 1174
   data/file.d 0
   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=1046
+  .hg/store/data/file.i: size=1174
+  $ hg tip
+  changeset:   1:3ce491143aec
+  tag:         tip
+  user:        test
+  date:        Thu Jan 01 00:00:00 1970 +0000
+  summary:     _
+  
+  $ hg verify
+  checking changesets
+  checking manifests
+  crosschecking files in changesets and manifests
+  checking files
+  checked 2 changesets with 2 changes to 1 files
   $ cd ..
diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -56,7 +56,7 @@ 
     unlink=True,
     checkambigfiles=None,
 ):
-    for f, o in entries:
+    for f, o in sorted(dict(entries).items()):
         if o or not unlink:
             checkambig = checkambigfiles and (f, b'') in checkambigfiles
             try: