Skip to content

Commit 6b00a1a

Browse files
KarthikNayakGit for Windows Build Agent
authored andcommitted
reftable: write correct max_update_index to header
In 297c09e (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 <[email protected]> Signed-off-by: Karthik Nayak <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d1d9a12 commit 6b00a1a

File tree

1 file changed

+3
-0
lines changed

1 file changed

+3
-0
lines changed

refs/reftable-backend.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,6 +1631,9 @@ static int reftable_be_transaction_finish(struct ref_store *ref_store UNUSED,
16311631
struct reftable_transaction_data *tx_data = transaction->backend_data;
16321632
int ret = 0;
16331633

1634+
if (tx_data->args)
1635+
tx_data->args->max_index = transaction->max_index;
1636+
16341637
for (size_t i = 0; i < tx_data->args_nr; i++) {
16351638
tx_data->args[i].max_index = transaction->max_index;
16361639

0 commit comments

Comments
 (0)