* Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems
@ 2026-05-13 8:18 Alexander Sandström
2026-05-13 15:42 ` D. Ben Knoble
2026-05-15 9:47 ` Torsten Bögershausen
0 siblings, 2 replies; 3+ messages in thread
From: Alexander Sandström @ 2026-05-13 8:18 UTC (permalink / raw)
To: git
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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems
2026-05-13 8:18 Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems Alexander Sandström
@ 2026-05-13 15:42 ` D. Ben Knoble
2026-05-15 9:47 ` Torsten Bögershausen
1 sibling, 0 replies; 3+ messages in thread
From: D. Ben Knoble @ 2026-05-13 15:42 UTC (permalink / raw)
To: Alexander Sandström; +Cc: git
On Wed, May 13, 2026 at 4:27 AM Alexander Sandström
<mail@alexandersandstrom.se> wrote:
>
> 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
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems
2026-05-13 8:18 Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems Alexander Sandström
2026-05-13 15:42 ` D. Ben Knoble
@ 2026-05-15 9:47 ` Torsten Bögershausen
1 sibling, 0 replies; 3+ messages in thread
From: Torsten Bögershausen @ 2026-05-15 9:47 UTC (permalink / raw)
To: Alexander Sandström, git
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
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-05-15 9:47 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-13 8:18 Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems Alexander Sandström
2026-05-13 15:42 ` D. Ben Knoble
2026-05-15 9:47 ` Torsten Bögershausen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox