Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 50348:f952be90b051 stable 6.4.2
revlog-split: make sure the self._indexfile attribut is reset (issue6811)
Before this change, after a transaction committing a file split, a revlog
object would have its `self._indexfile` attribute desynchronised from the
actual file storing the data. If that same object is reused (as we do for the
manifest during clone bundles), this lead to the data being writting in the
wrong location and the repository to go corrupt.
We not properly reset the attribut when applicable and everything is back in
working order.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 18 Apr 2023 01:23:27 +0200 |
parents | 87f0155d68aa |
children | 978ffa09910b 814f55775b21 |
comparison
equal
deleted
inserted
replaced
50347:2bb2a1ff4d8f | 50348:f952be90b051 |
---|---|
17 import collections | 17 import collections |
18 import contextlib | 18 import contextlib |
19 import io | 19 import io |
20 import os | 20 import os |
21 import struct | 21 import struct |
22 import weakref | |
22 import zlib | 23 import zlib |
23 | 24 |
24 # import stuff from node for others to import from revlog | 25 # import stuff from node for others to import from revlog |
25 from .node import ( | 26 from .node import ( |
26 bin, | 27 bin, |
2055 # this code | 2056 # this code |
2056 if side_write: | 2057 if side_write: |
2057 old_index_file_path = self._indexfile | 2058 old_index_file_path = self._indexfile |
2058 new_index_file_path = self._indexfile + b'.s' | 2059 new_index_file_path = self._indexfile + b'.s' |
2059 opener = self.opener | 2060 opener = self.opener |
2061 weak_self = weakref.ref(self) | |
2060 | 2062 |
2061 fncache = getattr(opener, 'fncache', None) | 2063 fncache = getattr(opener, 'fncache', None) |
2062 if fncache is not None: | 2064 if fncache is not None: |
2063 fncache.addignore(new_index_file_path) | 2065 fncache.addignore(new_index_file_path) |
2064 | 2066 |
2067 opener.rename( | 2069 opener.rename( |
2068 new_index_file_path, | 2070 new_index_file_path, |
2069 old_index_file_path, | 2071 old_index_file_path, |
2070 checkambig=True, | 2072 checkambig=True, |
2071 ) | 2073 ) |
2074 maybe_self = weak_self() | |
2075 if maybe_self is not None: | |
2076 maybe_self._indexfile = old_index_file_path | |
2077 | |
2078 def abort_callback(tr): | |
2079 maybe_self = weak_self() | |
2080 if maybe_self is not None: | |
2081 maybe_self._indexfile = old_index_file_path | |
2072 | 2082 |
2073 tr.registertmp(new_index_file_path) | 2083 tr.registertmp(new_index_file_path) |
2074 if self.target[1] is not None: | 2084 if self.target[1] is not None: |
2075 finalize_id = b'000-revlog-split-%d-%s' % self.target | 2085 callback_id = b'000-revlog-split-%d-%s' % self.target |
2076 else: | 2086 else: |
2077 finalize_id = b'000-revlog-split-%d' % self.target[0] | 2087 callback_id = b'000-revlog-split-%d' % self.target[0] |
2078 tr.addfinalize(finalize_id, finalize_callback) | 2088 tr.addfinalize(callback_id, finalize_callback) |
2089 tr.addabort(callback_id, abort_callback) | |
2079 | 2090 |
2080 new_dfh = self._datafp(b'w+') | 2091 new_dfh = self._datafp(b'w+') |
2081 new_dfh.truncate(0) # drop any potentially existing data | 2092 new_dfh.truncate(0) # drop any potentially existing data |
2082 try: | 2093 try: |
2083 with self._indexfp() as read_ifh: | 2094 with self._indexfp() as read_ifh: |