From a363d1f3175560fe7b2f0003f1a234a36351d30f Mon Sep 17 00:00:00 2001 From: atlas Date: Sat, 4 Jul 2026 20:09:33 +0200 Subject: [PATCH] docs(gotchas): document nix fmt failure in git worktrees --- docs/gotchas.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/docs/gotchas.md b/docs/gotchas.md index 7cfec7a7..153df0fa 100644 --- a/docs/gotchas.md +++ b/docs/gotchas.md @@ -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 '': 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:///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.