Volume XXII, number 280Wednesday, October 7, 2026Latest message 51 minutes ago

The Git List

News and archive of git@vger.kernel.org, since April 2005

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

3 messages between May 13, 2026 and May 15, 2026, from Alexander Sandström, D. Ben Knoble, Torsten Bögershausen.

Plain Markdown or JSON for tools and agents.

Alexander SandströmMay 13, 2026, 08:18 UTC on lore
Hello everyone,
I ran into a bug that took me a while to figure out. 

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

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

D. Ben KnobleMay 13, 2026, 15:42 UTC in reply to Alexander Sandström on lore

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

On Wed, May 13, 2026 at 4:27 AM Alexander Sandström <mail@alexandersandstrom.se> wrote:

Show 18 quoted lines
>
> Hello everyone,
>
> I ran into a bug that took me a while to figure out.
>
> 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.

See also https://lore.kernel.org/git/20240701033145.GB610406@coredump.intra.peff.net/ and https://lore.kernel.org/git/8BABB6F0-517F-4AA0-9FF9-92AF8C33CD0E@strongestfamilies.com/

In short, it's a known issue (that I don't think we're going to solve in the ref store where refs are just named files). Using reftables ought to make the papercuts go away.

-- 
D. Ben Knoble
Torsten BögershausenMay 15, 2026, 09:47 UTC in reply to Alexander Sandström on lore

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

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

Back to recent threads