git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re [bug] pull --prune could not delete references due to lock file already exists error

From
K Jayatheerth <jayatheerthkulkarni2005@gmail.com>
Date
Jun 25, 2025, 14:18 UTC
Message-ID
<20250625141849.78834-1-jayatheerthkulkarni2005@gmail.com>
In-Reply-To
<CAKkAvaw0sZ0sW9o_0NZdnZknS8M34UST3PetaPBQj5wwvJyjBA@mail.gmail.com>

First off thanks for reporting the bug :) So I cannot test this bug as my files system is case sensitive but to just read the code and give a thought in a direction (Assuming that the bug is recreatable)

int refs_delete_refs(struct ref_store *refs, const char *logmsg,
		     struct string_list *refnames, unsigned int flags)
{
...
	struct ref_transaction *transaction;
...
	for_each_string_list_item(item, refnames) {
		transaction = ref_store_transaction_begin(refs, 0, &err);
		if (!transaction) {
			warning(_("could not begin transaction to delete %s: %s"),
				item->string, err.buf);
			strbuf_reset(&err);
			failures = 1;
			continue;
		}
		ret = ref_transaction_delete(transaction, item->string,
					     NULL, NULL, flags, msg, &err);
		if (ret) {
			warning(_("could not delete reference %s: %s"),
				item->string, err.buf);
			strbuf_reset(&err);
			ref_transaction_free(transaction);
			failures = 1;
			continue;
		}
		ret = ref_transaction_commit(transaction, &err);
		if (ret) {
			warning(_("could not commit deletion of %s: %s"),
				item->string, err.buf);
			strbuf_reset(&err);
			failures = 1;
		}
		ref_transaction_free(transaction);
	}
	if (failures)
		ret = -1;
	strbuf_release(&err);
	free(msg);
	return ret;
}

The original implementation: Starts a single transaction using ref_store_transaction_begin(). Adds all deletions to that transaction. Commits the transaction. If any deletion fails, the entire transaction is aborted. On case-insensitive file systems, two refs like: may conflict at the file system level (e.g. both mapped to the same file or directory). If Git tries to delete both in one go, the transaction fails due to a lock file or unlink error. (Above are my assumptions till now).

What has changed is: Deletes each reference in its own transaction struct ref_transaction *transaction = ref_store_transaction_begin(...); ref_transaction_delete(transaction, ...); ref_transaction_commit(transaction, ...); ref_transaction_free(transaction); If one deletion fails due to a case conflict, the others still proceed. It avoids rolling back the entire prune operation just because of a single failure. Keeps failure count and returns appropriately Signals that something went wrong, but Git can now give partial success feedback.

The question I have is If this approach seems viable or perhaps any solution, would it be possible to write a test case for this scenario?

Thank you 
- Jayatheerth
Previous: ryenusNext: brian m. carlson
Message 2 of 14 in “[bug] pull --prune could not delete references due to lock file already exists error”
  1. ryenusJun 25, 2025
  2. Re [bug] pull --prune could not delete references due to lock file already exists errorK Jayatheerth, Jun 25, 2025
  3. brian m. carlsonJun 27, 2025
  4. JAYATHEERTH KJun 30, 2025
  5. Karthik NayakJun 30, 2025
  6. brian m. carlsonJun 30, 2025
  7. Junio C HamanoJun 30, 2025
  8. Patrick SteinhardtJul 1, 2025
  9. Junio C HamanoJul 1, 2025
  10. Patrick SteinhardtJul 2, 2025
  11. Karthik NayakJul 1, 2025
  12. Chris TorekJul 2, 2025
  13. Junio C HamanoJul 2, 2025
  14. JAYATHEERTH KJul 1, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.