docs(gotchas): document nix fmt failure in git worktrees
This commit is contained in:
parent
c594de07ca
commit
a363d1f317
1 changed files with 30 additions and 0 deletions
|
|
@ -385,3 +385,33 @@ Why `builtins.unsafeDiscardStringContext`? The path string
|
||||||
make `builtins.path` include `self` as a build dependency even after
|
make `builtins.path` include `self` as a build dependency even after
|
||||||
content-addressing the directory. Discarding the context makes the
|
content-addressing the directory. Discarding the context makes the
|
||||||
resulting `nixSrc` truly independent of `self`'s store path.
|
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.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue