Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/revlog.py @ 51505:3cf9e52f5e27 stable
inline-changelog: fix a critical bug in write_pending that delete data
Since a93e52f0b6ff we no longer use inline-revlog for the changelog. The goal there was to
solve the lack of testing for the two variants (inline vs split) and reduce the
complexity of the interaction with "diverted-write" on the changelog level.
However many existing repository still have inline-changelog and we
automatically move them to normal revlog as soon as we have the chances.
Unfortunately This conversion is buggy and can result in the destruction of the
changelog.i if hook triggers the "write pending" mechanism.
The bugs comes from the "revlog splitting" logic and the "write_pending" logic
stepping over each other. Ironically the change in a93e52f0b6ff aims at no
longer having this kind of problem.
This changesets fix this issue and add associated tests.
Fixing this reveal that the transaction hooks end up not seeing the pending
transaction content, because the name is not right ("changelog.i.s.a" instead of
"changelog.i.s") we fix this in the next changeset.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Wed, 12 Jun 2024 02:15:20 +0200 |
parents | def497c75351 |
children | 1721d983dd6d |
comparison
equal
deleted
inserted
replaced
51504:553eb132366f | 51505:3cf9e52f5e27 |
---|---|
2893 maybe_self._indexfile = old_index_file_path | 2893 maybe_self._indexfile = old_index_file_path |
2894 maybe_self._inner.inline = True | 2894 maybe_self._inner.inline = True |
2895 maybe_self._inner.index_file = old_index_file_path | 2895 maybe_self._inner.index_file = old_index_file_path |
2896 | 2896 |
2897 tr.registertmp(new_index_file_path) | 2897 tr.registertmp(new_index_file_path) |
2898 # we use 001 here to make this this happens after the finalisation of | |
2899 # pending changelog write (using 000). Otherwise the two finalizer | |
2900 # would step over each other and delete the changelog.i file. | |
2898 if self.target[1] is not None: | 2901 if self.target[1] is not None: |
2899 callback_id = b'000-revlog-split-%d-%s' % self.target | 2902 callback_id = b'001-revlog-split-%d-%s' % self.target |
2900 else: | 2903 else: |
2901 callback_id = b'000-revlog-split-%d' % self.target[0] | 2904 callback_id = b'001-revlog-split-%d' % self.target[0] |
2902 tr.addfinalize(callback_id, finalize_callback) | 2905 tr.addfinalize(callback_id, finalize_callback) |
2903 tr.addabort(callback_id, abort_callback) | 2906 tr.addabort(callback_id, abort_callback) |
2904 | 2907 |
2905 self._format_flags &= ~FLAG_INLINE_DATA | 2908 self._format_flags &= ~FLAG_INLINE_DATA |
2906 self._inner.split_inline( | 2909 self._inner.split_inline( |