branching: merge stable into default
authorRaphaël Gomès <rgomes@octobus.net>
Tue, 18 Apr 2023 11:55:23 +0200
changeset 50483 6b916efe6af6
parent 50482 a0e39f5bb7cd (current diff)
parent 50351 de2102390910 (diff)
child 50484 608a69d5d38f
branching: merge stable into default
tests/test-clonebundles.t
--- a/.hgsigs	Fri Apr 14 19:59:44 2023 +0100
+++ b/.hgsigs	Tue Apr 18 11:55:23 2023 +0200
@@ -242,3 +242,4 @@
 05de4896508e8ec387b33eb30d8aab78d1c8e9e4 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmQBI2AZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVrRZC/wJyPOJoxpjEJZaRoBmWtkOlf0Y0TyEb6wd8tZIVALNDYZMSMqT7UBjFmaZijOYndUW7ZCj1hKShaIw80vY/hjJ3KZMODY9t91SOwmrVaGrCUeF1tXkuhEgwxfkekPWLxYYc688gLb6oc3FBm//lucNGrOWBXw6yhm1dUcndHXXpafjJslKAHwJN7vI5q69SxvS6SlJUzh/RFWYLnbZ2Qi35ixkU12FZiYVzxDl2i7XbhVoT5mit6VTU7Wh4BMSYuorAv937sF9Y6asE7sQUYHC2C2qjp8S5uFXV/IrhCPbJyWVc4ymPm58Eh6SmItC9zHDviFF9aFoZMK/lfK3Dqumu3T9x6ZYcxulpjNsM0/yv9OiiWbw33PnNb74A9uwrxZHB3XexXiigBUlUzO4lJQ5Oe1rhpPfPPRVyxaeZ8/cPmoJjCuwoiG0YtUeNH5PkHi05O0/hLR9PftDY8oMyzOBErSqjMjZ6OTkFFgk3dI9rHU72C1KL9Jh5uHwEQchBmg=
 f14864fffdcab725d9eac6d4f4c07be05a35f59a 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmQc3KUZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVnYZDACh1Bcj8Yu3t8pO22SKWJnz8Ndw9Hvw+ifLaRxFUxKtqUYvy3CIl2qt8k7V13M25qw0061SKgcvNdjtkOhdmtFHNAbqryy0nK9oSZ2GfndmJfMxm9ixF/CcHrx+MmsklEz2woApViHW5PrmgKvZNsStQ5NM457Yx3B4nsT9b8t03NzdNiZRM+RZOkZ+4OdSbiB6hYuTqEFIi2YM+gfVM5Z7H8sEFBkUCtuwUjFGaWThZGGhAcqD5E7p/Lkjv4e4tzyHOzHDgdd+OCAkcbib6/E3Q1MlQ1x7CKpJ190T8R35CzAIMBVoTSI+Ov7OKw1OfGdeCvMVJsKUvqY3zrPawmJB6pG7GoVPEu5pU65H51U3Plq3GhsekUrKWY/BSHV9FOqpKZdnxOAllfWcjLYpbC/fM3l8uuQVcPAs89GvWKnDuE/NWCDYzDAYE++s/H4tP3Chv6yQbPSv/lbccst7OfLLDtXgRHIyEWLo392X3mWzhrkNtfJkBdi39uH9Aoh7pN0=
 83ea6ce48b4fd09fb79c4e34cc5750c805699a53 0 iQHNBAABCgA3FiEEH2b4zfZU6QXBHaBhoR4BzQ4F2VYFAmQ3860ZHGFscGhhcmVAcmFwaGFlbGdvbWVzLmRldgAKCRChHgHNDgXZVk3gDACIIcQxKfis/r5UNj7SqyFhQxUCo8Njp7zdLFv3CSWFdFiOpQONI7Byt9KjwedUkUK9tqdb03V7W32ZSBTrNLM11uHY9E5Aknjoza4m+aIGbamEVRWIIHXjUZEMKS9QcY8ElbDvvPu/xdZjyTEjNNiuByUpPUcJXVzpKrHm8Wy3GWDliYBuu68mzFIX3JnZKscdK4EjCAfDysSwwfLeBMpd0Rk+SgwjDwyPWAAyU3yDPNmlUn8qTGHjXxU3vsHCXpoJWkfKmQ9n++23WEpM9vC8zx2TIy70+gFUvKG77+Ucv+djQxHRv0L6L5qUSBJukD3R3nml1xu6pUeioBHepRmTUWgPbHa/gQ+J2Pw+rPCK51x0EeT0SJjxUR2mmMLbk8N2efM35lEjF/sNxotTq17Sv9bjwXhue6BURxpQDEyOuSaS0IlF56ndXtE/4FX3H6zgU1+3jw5iBWajr1E04QjPlSOJO7nIKYM9Jq3VpHR7MiFwfT46pJEfw9pNgZX2b8o=
+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
--- a/.hgtags	Fri Apr 14 19:59:44 2023 +0100
+++ b/.hgtags	Tue Apr 18 11:55:23 2023 +0200
@@ -258,3 +258,4 @@
 05de4896508e8ec387b33eb30d8aab78d1c8e9e4 6.4rc0
 f14864fffdcab725d9eac6d4f4c07be05a35f59a 6.4
 83ea6ce48b4fd09fb79c4e34cc5750c805699a53 6.4.1
+f952be90b0514a576dcc8bbe758ce3847faba9bb 6.4.2
--- a/mercurial/revlog.py	Fri Apr 14 19:59:44 2023 +0100
+++ b/mercurial/revlog.py	Tue Apr 18 11:55:23 2023 +0200
@@ -19,6 +19,7 @@
 import io
 import os
 import struct
+import weakref
 import zlib
 
 # import stuff from node for others to import from revlog
@@ -2057,6 +2058,7 @@
             old_index_file_path = self._indexfile
             new_index_file_path = self._indexfile + b'.s'
             opener = self.opener
+            weak_self = weakref.ref(self)
 
             fncache = getattr(opener, 'fncache', None)
             if fncache is not None:
@@ -2069,13 +2071,22 @@
                     old_index_file_path,
                     checkambig=True,
                 )
+                maybe_self = weak_self()
+                if maybe_self is not None:
+                    maybe_self._indexfile = old_index_file_path
+
+            def abort_callback(tr):
+                maybe_self = weak_self()
+                if maybe_self is not None:
+                    maybe_self._indexfile = old_index_file_path
 
             tr.registertmp(new_index_file_path)
             if self.target[1] is not None:
-                finalize_id = b'000-revlog-split-%d-%s' % self.target
+                callback_id = b'000-revlog-split-%d-%s' % self.target
             else:
-                finalize_id = b'000-revlog-split-%d' % self.target[0]
-            tr.addfinalize(finalize_id, finalize_callback)
+                callback_id = b'000-revlog-split-%d' % self.target[0]
+            tr.addfinalize(callback_id, finalize_callback)
+            tr.addabort(callback_id, abort_callback)
 
         new_dfh = self._datafp(b'w+')
         new_dfh.truncate(0)  # drop any potentially existing data
--- a/relnotes/6.4	Fri Apr 14 19:59:44 2023 +0100
+++ b/relnotes/6.4	Tue Apr 18 11:55:23 2023 +0200
@@ -1,3 +1,11 @@
+= Mercurial 6.4.2 =
+
+Exceptional bugfix release due to a corruption bug that happens when using
+clonebundles on repositories with large files.
+
+ * revlog-split: make sure the self._indexfile attribute is reset (issue6811)
+
+
 = Mercurial 6.4.1 =
 
  * rhg: fix a bug in path encoding
--- a/tests/test-bundle2-multiple-changegroups.t	Fri Apr 14 19:59:44 2023 +0100
+++ b/tests/test-bundle2-multiple-changegroups.t	Tue Apr 18 11:55:23 2023 +0200
@@ -455,3 +455,103 @@
   |
   o  0:4a2df7238c3b public test  A
   
+
+Test that "split" from inline content works fine (cf issue6811)
+===============================================================
+
+setup
+-----
+
+(create a compression free version where the split is easier to trigger)
+
+  $ cat >> $HGRCPATH << EOF
+  > [format]
+  > revlog-compression=none
+  > use-persistent-nodemap=no
+  > EOF
+
+  $ cd ..
+  $ hg clone --pull repo repo-test-split --quiet
+  pullop.cgresult is 2
+  $ cat > repo-test-split/.hg/hgrc << EOF
+  > [extensions]
+  > bundle2=$TESTTMP/bundle2.py
+  > EOF
+  $ hg clone --pull repo-test-split clone-test-split --quiet
+  pullop.cgresult is 2
+  $ cd repo-test-split
+  $ cat > .hg/hgrc << EOF
+  > [extensions]
+  > bundle2=$TESTTMP/bundle2.py
+  > EOF
+
+
+IMPORTANT: must be a non-split revlog with only a .i
+  $ ls -1 .hg/store/00manifest.*
+  .hg/store/00manifest.i
+  $ ls -1 .hg/store/data/_a.*
+  .hg/store/data/_a.i
+
+  $ $TESTDIR/seq.py 100000 > A
+  $ mkdir foo
+  $ cd foo
+  $ touch `$TESTDIR/seq.py 10000`
+  $ cd ..
+  $ hg add -q foo
+  $ hg commit -m 'split the manifest and one filelog'
+
+
+IMPORTANT: now the revlogs must be split
+  $ ls -1 .hg/store/00manifest.*
+  .hg/store/00manifest.d
+  .hg/store/00manifest.i
+  $ ls -1 .hg/store/data/_a.*
+  .hg/store/data/_a.d
+  .hg/store/data/_a.i
+
+Add an extra commit on top of that
+
+  $ echo foo >> A
+  $ hg commit -m 'one extra commit'
+
+
+Actual testing
+--------------
+
+  $ cd ../clone-test-split
+
+We now pull this in the clone the split should be in one changegroup, the update in another one
+
+  $ hg  pull
+  pulling from $TESTTMP/repo-test-split
+  searching for changes
+  remote: changegroup1
+  adding changesets
+  adding manifests
+  adding file changes
+  remote: changegroup2
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 10002 changes to 10002 files
+  new changesets 5e5bf9c91085:900b170f70d0
+  pullop.cgresult is 1
+  (run 'hg update' to get a working copy)
+
+IMPORTANT: now the revlogs must be split
+  $ ls -1 .hg/store/00manifest.*
+  .hg/store/00manifest.d
+  .hg/store/00manifest.i
+  $ ls -1 .hg/store/data/_a.*
+  .hg/store/data/_a.d
+  .hg/store/data/_a.i
+
+manifest should work
+
+  $ hg  files -r tip | wc -l
+  \s*10007 (re)
+
+file content should work
+
+  $ hg  cat -r tip A | wc -l
+  \s*100001 (re)
--- a/tests/test-clonebundles.t	Fri Apr 14 19:59:44 2023 +0100
+++ b/tests/test-clonebundles.t	Tue Apr 18 11:55:23 2023 +0200
@@ -638,3 +638,114 @@
   updating the branch cache
   (sent 4 HTTP requests and * bytes; received * bytes in responses) (glob)
   $ killdaemons.py
+
+Testing a clone bundles that involves revlog splitting (issue6811)
+==================================================================
+
+  $ cat >> $HGRCPATH << EOF
+  > [format]
+  > revlog-compression=none
+  > use-persistent-nodemap=no
+  > EOF
+
+  $ hg init server-revlog-split/
+  $ cd server-revlog-split
+  $ cat >> .hg/hgrc << EOF
+  > [extensions]
+  > clonebundles =
+  > EOF
+  $ echo foo > A
+  $ hg add A
+  $ hg commit -m 'initial commit'
+IMPORTANT: the revlogs must not be split
+  $ ls -1 .hg/store/00manifest.*
+  .hg/store/00manifest.i
+  $ ls -1 .hg/store/data/_a.*
+  .hg/store/data/_a.i
+
+do big enough update to split the revlogs
+
+  $ $TESTDIR/seq.py 100000 > A
+  $ mkdir foo
+  $ cd foo
+  $ touch `$TESTDIR/seq.py 10000`
+  $ cd ..
+  $ hg add -q foo
+  $ hg commit -m 'split the manifest and one filelog'
+
+IMPORTANT: now the revlogs must be split
+  $ ls -1 .hg/store/00manifest.*
+  .hg/store/00manifest.d
+  .hg/store/00manifest.i
+  $ ls -1 .hg/store/data/_a.*
+  .hg/store/data/_a.d
+  .hg/store/data/_a.i
+
+Add an extra commit on top of that
+
+  $ echo foo >> A
+  $ hg commit -m 'one extra commit'
+
+  $ cd ..
+
+Do a bundle that contains the split, but not the update
+
+  $ hg bundle --exact --rev '::(default~1)' -R server-revlog-split/ --type gzip-v2 split-test.hg
+  2 changesets found
+
+  $ cat > server-revlog-split/.hg/clonebundles.manifest << EOF
+  > http://localhost:$HGPORT1/split-test.hg BUNDLESPEC=gzip-v2
+  > EOF
+
+start the necessary server
+
+  $ "$PYTHON" $TESTDIR/dumbhttp.py -p $HGPORT1 --pid http.pid
+  $ cat http.pid >> $DAEMON_PIDS
+  $ hg -R server-revlog-split serve -d -p $HGPORT --pid-file hg.pid --accesslog access.log
+  $ cat hg.pid >> $DAEMON_PIDS
+
+Check that clone works fine
+===========================
+
+Here, the initial clone will trigger a revlog split (which is a bit clowny it
+itself, but whatever). The split revlogs will see additionnal data added to
+them in the subsequent pull. This should not be a problem
+
+  $ hg clone http://localhost:$HGPORT revlog-split-in-the-bundle
+  applying clone bundle from http://localhost:$HGPORT1/split-test.hg
+  adding changesets
+  adding manifests
+  adding file changes
+  added 2 changesets with 10002 changes to 10001 files
+  finished applying clone bundle
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files
+  new changesets e3879eaa1db7
+  2 local changesets published
+  updating to branch default
+  10001 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+check the results
+
+  $ cd revlog-split-in-the-bundle
+  $ f --size .hg/store/00manifest.*
+  .hg/store/00manifest.d: size=499037
+  .hg/store/00manifest.i: size=192
+  $ f --size .hg/store/data/_a.*
+  .hg/store/data/_a.d: size=588917
+  .hg/store/data/_a.i: size=192
+
+manifest should work
+
+  $ hg  files -r tip | wc -l
+  \s*10001 (re)
+
+file content should work
+
+  $ hg  cat -r tip A | wc -l
+  \s*100001 (re)
+
+