diff options
| author | Karthik Nayak <karthik.188@gmail.com> | 2025-01-15 11:54:51 +0000 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-01-15 09:12:09 -0800 |
| commit | bc67b4ab5f8bc268ecd2d9bb7dc1b7bf26884a8e (patch) | |
| tree | 16524e1388f4d785ba359eb507b7755d3d114c3b /t/t1460-refs-migrate.sh | |
| parent | 8ddcdc1bb33ccf803461dd2365146f9341bf9312 (diff) | |
| download | git-bc67b4ab5f8bc268ecd2d9bb7dc1b7bf26884a8e.tar.xz | |
reftable: write correct max_update_index to header
In 297c09eabb (refs: allow multiple reflog entries for the same refname,
2024-12-16), the reftable backend learned to handle multiple reflog
entries within the same transaction. This was done modifying the
`update_index` for reflogs with multiple indices. During writing the
logs, the `max_update_index` of the writer was modified to ensure the
limits were raised to the modified `update_index`s.
However, since ref entries are written before the modification to the
`max_update_index`, if there are multiple blocks to be written, the
reftable backend writes the header with the old `max_update_index`. When
all logs are finally written, the footer will be written with the new
`min_update_index`. This causes a mismatch between the header and the
footer and causes the reftable file to be corrupted. The existing tests
only spawn a single block and since headers are lazily written with the
first block, the tests didn't capture this bug.
To fix the issue, the appropriate `max_update_index` limit must be set
even before the first block is written. Add a `max_index` field to the
transaction which holds the `max_index` within all its updates, then
propagate this value to the reftable backend, wherein this is used to
the set the `max_update_index` correctly.
Add a test which creates a few thousand reference updates with multiple
reflog entries, which should trigger the bug.
Reported-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't/t1460-refs-migrate.sh')
| -rwxr-xr-x | t/t1460-refs-migrate.sh | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/t/t1460-refs-migrate.sh b/t/t1460-refs-migrate.sh index f59bc4860f..307b2998ef 100755 --- a/t/t1460-refs-migrate.sh +++ b/t/t1460-refs-migrate.sh @@ -227,6 +227,18 @@ do done done +test_expect_success 'multiple reftable blocks with multiple entries' ' + test_when_finished "rm -rf repo" && + git init --ref-format=files repo && + test_commit -C repo first && + printf "create refs/heads/ref-%d HEAD\n" $(test_seq 5000) >stdin && + git -C repo update-ref --stdin <stdin && + test_commit -C repo second && + printf "update refs/heads/ref-%d HEAD\n" $(test_seq 3000) >stdin && + git -C repo update-ref --stdin <stdin && + test_migration repo reftable +' + test_expect_success 'migrating from files format deletes backend files' ' test_when_finished "rm -rf repo" && git init --ref-format=files repo && |
