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

Re: Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems

From
Torsten Bögershausen <tboegi@web.de>
Date
May 15, 2026, 09:47 UTC
Message-ID
<a77695ea-ae24-45ca-8c14-966e25bb90ba@web.de>
In-Reply-To
<95BE8E60-1684-4E0A-9E46-E61E81D06CE1@alexandersandstrom.se>
On 2026-05-13 10:18, Alexander Sandström wrote:
> Hello everyone,
> 
> I ran into a bug that took me a while to figure out.
Thanks for the report.
Show 28 quoted lines
> 
> I'm sadly not a good enough C programmer to submit a proper patch,
> but perhaps this bug report will at least be indexed by search engines
> and help others that might have this issue to understand the cause.
> 
> My guess is that it will happen much more frequently now that
> worktrees are more popular.
> 
> **Report**
> 
> On case-insensitive filesystems (macOS APFS/HFS+), `git rev-parse head`
> (lowercase) in a linked worktree resolves to the main worktree's HEAD
> rather than the current worktree's HEAD. This causes commands like
> `git reset --soft head~1` to silently operate on the wrong commit.
> 
> **Setup**
> 
> ```sh
> $ git init main && cd main
> $ git commit --allow-empty -m "base"
> $ git commit --allow-empty -m "main-only"
> $ git worktree add ../linked HEAD~1
> $ cd ../linked
> $ git commit --allow-empty -m "linked-only"
> ```
> 
> **Expected** `head` and `HEAD` resolve to the same commit in the
> linked worktree (or `head` is rejected as an unknown revision).

This is probably not what you expect. head should not be used at all, since it is not a valid reference.

When using case-insensitive file systems, head and HEAD may be the same, but that is not a feature.

In theory, we may be able to refuse head on a case insensitive file system. And Head, hEad, HEad, you got it.

In practice nobody has done that yet. And a quick search for git refs case insensitive shows a lot of reports about the limitations that a case insensitive file system gives you.

And yes, you can format a partition on MacOs case-insensitive. Or live with the limitations that arise. Or send a patch. For the documentation.

HTH
Show 45 quoted lines
> 
> **Actual**
> 
> ```
> $ cd ../linked
> $ git rev-parse HEAD
> <commit: "linked-only">
> $ git rev-parse head
> <commit: "main-only">
> ```
> 
> `HEAD` (uppercase) correctly resolves via the per-worktree ref at
> `.git/worktrees/linked/HEAD`. But lowercase `head` falls through to
> general ref resolution, which opens a file named `head` on disk. On a
> case-insensitive filesystem, this matches `.git/HEAD`, the main
> worktree's HEAD, instead of the linked worktree's HEAD.
> 
> Without worktrees the bug is latent: `.git/HEAD` is the only HEAD file,
> so the wrong codepath happens to produce the correct result. The bug
> becomes observable only with linked worktrees, where the main and linked
> worktree HEADs diverge.
> 
> **Impact** `git reset --soft head~1` in a linked worktree silently
> resets to the wrong commit, staging unexpected changes. This is
> particularly confusing because there is no error or warning. The
> command appears to succeed.
> 
> I realize one argument might simply be "lower-case head isn't a thing",
> so feel free to disregard if that is the projects stance.
> 
> **Possible fix** During ref resolution, when the input string matches
> `HEAD` case-insensitively but is not exactly `HEAD`, git could either:
> - reject it with an error (matching Linux behavior, where lowercase
>    `head` fails with "unknown revision"), or
> - normalize it to `HEAD` and route through the per-worktree codepath.
> 
> **Environment**
> - git 2.53.0
> - macOS 15.6 (APFS, case-insensitive)
> 
> 
> Regards,
> Alexander
> 
> 
Previous: D. Ben Knoble
Message 3 of 3 in “Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems”
  1. Alexander SandströmMay 13, 2026
  2. D. Ben KnobleMay 13, 2026
  3. Torsten BögershausenMay 15, 2026

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.