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

Re: "lock file exists" when fetching in bare clone of repository

From
Karthik Nayak <karthik.188@gmail.com>
Date
Aug 22, 2025, 08:01 UTC
Message-ID
<CAOLa=ZS43w74tWjD47h2mnGiyaQWrGEY-UpL8kdXJi_zD0ASmw@mail.gmail.com>
In-Reply-To
<aKgKmLvaHAuueJeb@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
Show 25 quoted lines
> On Thu, Aug 21, 2025 at 09:05:30AM -0700, Junio C Hamano wrote:
>> Patrick Steinhardt <ps@pks.im> writes:
>>
>> >     You're on a case-insensitive filesystem, and the remote you are
>> >     trying to fetch from has references that only differ in casing. It
>> >     is impossible to store such references with the "files" backend. You
>>
>> "backend." -> "backend on your system."
>>
>> >     can either accept this as-is, in which case you won't be able to
>> >     store all remote references on disk. Or you can alternatively
>>
>> I do not see the former as a viable choice, though.  When this
>> happens, the clone or fetch fails and the user cannot catch up to
>> the upstream development, no?  You have to futz with the fetch
>> refspec to cause refs your filesystem cannot store ignored in order
>> to make progress on other refs, but that is making the user do more
>> than accepting this as-is.
>
> Oh, yes, right now it's too involved. What I'm proposing is to mark the
> transaction as allowed-to-fail, and in that case we'd be able to fetch
> and store refs in this case again. The result would still be broken, but
> it would be broken in a similar way as before. There's one difference
> though: we'd accept the _first_ conflicting ref now, whereas before we
> accepted the _last_ conflicting ref.

I replied to one of the earlier emails, but ended up only sending it to Peff by mistake. Re-sending parts of it now.

The fix itself isn't too involved:
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 088b52c740..5c31b02e6b 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -776,6 +776,8 @@ 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)
+				ret = REF_TRANSACTION_ERROR_NAME_CONFLICT;
            goto error_return;
        }
    }


and this would fix the issue, when tested on a case-insensitive filesystem:

  $ ~/code/git/build/bin-wrappers/git fetch -f origin
'refs/heads/*:refs/heads/*'
  remote: Enumerating objects: 15, done.
  remote: Counting objects: 100% (15/15), done.
  remote: Compressing objects: 100% (9/9), done.
  remote: Total 15 (delta 3), reused 0 (delta 0), pack-reused 0 (from 0)
  Unpacking objects: 100% (15/15), 3.54 KiB | 3.54 MiB/s, done.
  From https://gitlab.com/knayakgl/case-insensitive-refs
   * [new branch]      SampLe     -> SampLe
   * [new branch]      Sample     -> Sample
   * [new branch]      main       -> main
   * [new branch]      sample     -> sample
   * [new branch]      SampLe     -> origin/SampLe
   * [new branch]      Sample     -> origin/Sample
   * [new branch]      main       -> origin/main
   * [new branch]      sample     -> origin/sample
  error: some local refs could not be updated; try running
   'git remote prune origin' to remove any old, conflicting branches
  error: fetching ref refs/heads/sample failed: refname conflict
  error: fetching ref refs/remotes/origin/Sample failed: refname conflict
  error: fetching ref refs/remotes/origin/sample failed: refname conflict

  $ git for-each-ref
  24abc5ed19b517692bb4245eb4185dd5a86d7376 commit	refs/heads/SampLe
  24abc5ed19b517692bb4245eb4185dd5a86d7376 commit	refs/heads/main
  24abc5ed19b517692bb4245eb4185dd5a86d7376 commit	refs/remotes/origin/SampLe
  24abc5ed19b517692bb4245eb4185dd5a86d7376 commit	refs/remotes/origin/main

But like you noted, we end up saving the first reference rather than the
last. Either isn't ideal, so while there is a change in behavior, this
is better than the complete failure of the command.

> In any case, I very much feel like we should know to warn about this
> case and guide readers towards a proper solution.
>
> Patrick
Previous: Patrick SteinhardtNext: Junio C Hamano
Message 8 of 16 in “"lock file exists" when fetching in bare clone of repository”
  1. Joe DrewAug 20, 2025
  2. Jeff KingAug 20, 2025
  3. Patrick SteinhardtAug 21, 2025
  4. Jeff KingAug 21, 2025
  5. Patrick SteinhardtAug 21, 2025
  6. Junio C HamanoAug 21, 2025
  7. Patrick SteinhardtAug 22, 2025
  8. Karthik NayakAug 22, 2025
  9. Junio C HamanoAug 22, 2025
  10. Karthik NayakAug 28, 2025
  11. Junio C HamanoAug 28, 2025
  12. Karthik NayakSep 1, 2025
  13. Junio C HamanoAug 21, 2025
  14. Joe DrewAug 22, 2025
  15. Jeff KingAug 26, 2025
  16. Patrick SteinhardtSep 2, 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.