docs(gotchas): document nix fmt failure in git worktrees

This commit is contained in:
atlas 2026-07-04 20:09:33 +02:00 committed by mara
commit a363d1f317

View file

@ -385,3 +385,33 @@ Why `builtins.unsafeDiscardStringContext`? The path string
make `builtins.path` include `self` as a build dependency even after
content-addressing the directory. Discarding the context makes the
resulting `nixSrc` truly independent of `self`'s store path.
### `nix fmt` fails in a git worktree with "object not found"
`nix fmt` (and any `nix` command that fetches a `git+file://` flake
URL) uses libgit2 internally to compute `revCount` — the number of
commits reachable from HEAD. This walk fails with:
```
error: getting Git object '<hash>': object not found (libgit2 error code = 9)
```
when a commit that was reachable at some earlier evaluation is now gone
(GC'd, rebased away, or pruned). The failure is persistent: clearing
`~/.cache/nix/{eval-cache-v6,gitv3,fetcher-cache-v4.sqlite}` does not
help because the missing object is a structural gap in the git object
graph itself, not in nix's caches.
**Workaround: use a plain clone, not a git worktree.**
```bash
git clone http://<forge>/hyperhive/hyperhive.git ~/hh-work
cd ~/hh-work && nix fmt
```
The root cause is specific to worktrees: a worktree shares the object
store with its parent repo. If the parent repo's history was rewritten
(rebase, force-push, `git gc --prune`) while the worktree was checked
out at a branch tip that references the pruned commits via its reflog or
history, libgit2's rev-walk encounters the gap. A plain clone has its
own self-consistent object store and is immune to the issue.