From: Torsten Bögershausen Date: Fri, 15 May 2026 09:47:05 GMT Subject: Re: Bug: lowercase "head" resolves to wrong commit in linked worktrees on case-insensitive filesystems Message-ID: 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. > > 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 > > $ git rev-parse head > > ``` > > `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 > >