Re: [PATCH v3 2/4] refs/files: use correct error type when lock exists
From: Karthik Nayak <hidden>
Date: 2025-09-17 07:39:33
Justin Tobler [off-list ref] writes:
On 25/09/13 10:54PM, Karthik Nayak wrote:quoted
When fetching references into a repository, if a lock for a particular reference exists, then `lock_raw_ref()` throws: - REF_TRANSACTION_ERROR_CASE_CONFLICT: when there is a conflict because transaction contains conflicting references while being on as/transaction/the transaction/
Makes sense.
quoted
case-insensitive filesystem. - REF_TRANSACTION_ERROR_GENERIC: for all other errors. The latter causes the entire set of batched updates to fail, even in case sensitive filessystems.Ok so this issue isn't related to case-insensitive filesystems. The issue is that now we use batch updated, a single pre-existing lockfile causes the entire transaction to fail. Prior to batch updates, only the individual update would fail, but wouldn't stop others.quoted
Instead, return a 'REF_TRANSACTION_ERROR_CREATE_EXISTS' error. This allows batched updates to reject the individual update which conflicts with the existing file, while updating the rest of the references.Make sense.quoted
Signed-off-by: Karthik Nayak <redacted> --- refs/files-backend.c | 20 +++++++++++++++++--- t/t5510-fetch.sh | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-)diff --git a/refs/files-backend.c b/refs/files-backend.c index 01df32904b..69e50a16db 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c@@ -797,9 +797,23 @@ static enum ref_transaction_error lock_raw_ref(struct files_ref_store *refs, goto retry; } else { unable_to_lock_message(ref_file.buf, myerr, err); - if (myerr == EEXIST && ignore_case && - transaction_has_case_conflicting_update(transaction, update)) - ret = REF_TRANSACTION_ERROR_CASE_CONFLICT; + if (myerr == EEXIST) { + if (ignore_case && + transaction_has_case_conflicting_update(transaction, update)) + /* + * In case-insensitive filesystems, ensure that conflicts within a + * given transaction are handled. Pre-existing refs on a + * case-insensitive system will be overridden without any issue. + */ + ret = REF_TRANSACTION_ERROR_CASE_CONFLICT; + else + /* + * Pre-existing case-conflicting reference locks should also be + * specially categorized to avoid failing all batched updates. + */ + ret = REF_TRANSACTION_ERROR_CREATE_EXISTS;IIUC, by returning a non-generic error here the individual reference will be rejected during batch updates instead of aborting the transaction. -Justin
Indeed. Batched updates allow rejecting of individual updates. It only aborts when faced with a GENERIC error. So by marking this as non-generic, it doesn't change the flow for regular transactions but only how batched updates would handle it.
Attachments
- signature.asc [application/pgp-signature] 690 bytes