diff options
| author | Karthik Nayak <karthik.188@gmail.com> | 2025-06-20 09:15:44 +0200 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2025-06-25 08:20:27 -0700 |
| commit | 15c45c745872af43df08c60979476520165a1df1 (patch) | |
| tree | e4352f32a2a52189aaf6010ad2fa6e0b1da2f638 /refs/files-backend.c | |
| parent | 9d2962a7c44fd5f9abec634d05fe28cdafd60036 (diff) | |
refs/files: skip updates with errors in batched updates
The commit 23fc8e4f61 (refs: implement batch reference update support,
2025-04-08) introduced support for batched reference updates. This
allows users to batch updates together, while allowing some of the
updates to fail.
Under the hood, batched updates use the reference transaction mechanism.
Each update which fails is marked as such. Any failed updates must be
skipped over in the rest of the code, as they wouldn't apply any more.
In two of the loops within 'files_transaction_finish()' of the files
backend, the failed updates aren't skipped over. This can cause a
SEGFAULT otherwise. Add the missing skips and a test to validate the
same.
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'refs/files-backend.c')
| -rw-r--r-- | refs/files-backend.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c index 4d1f65a57a..c4a0f29072 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -3208,6 +3208,10 @@ static int files_transaction_finish(struct ref_store *ref_store, */ for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; + + if (update->rejection_err) + continue; + if (update->flags & REF_DELETING && !(update->flags & REF_LOG_ONLY) && !(update->flags & REF_IS_PRUNING)) { @@ -3239,6 +3243,9 @@ static int files_transaction_finish(struct ref_store *ref_store, struct ref_update *update = transaction->updates[i]; struct ref_lock *lock = update->backend_data; + if (update->rejection_err) + continue; + if (update->flags & REF_DELETING && !(update->flags & REF_LOG_ONLY)) { update->flags |= REF_DELETED_RMDIR; |
