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

From: Torsten Bögershausen <[email-masked]>
Date: Fri, 15 May 2026 11:47:05 +0200

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.
> 
> 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

> 
> **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
> 
>