Worktree isolation litters dev\null\ hook files in Git LFS repos on Windows
Environment
- Claude Code 2.0.42, Windows 11 Pro (10.0.26200)
- git version 2.55.0.windows.3, git-lfs/3.7.1 (windows amd64)
- Repo: git worktrees via the Agent tool's
isolation: "worktree"/ built-in worktree
creation under .claude/worktrees/; repo has ~500 Git LFS–tracked files
What happens
Every worktree Claude Code creates in this repo ends up with four untracked junk files:
<worktree>\dev\null\post-checkout
<worktree>\dev\null\post-commit
<worktree>\dev\null\post-merge
<worktree>\dev\null\pre-push
They are copies of the Git LFS hook stubs, written at worktree-creation time (file mtimes
land within ~0.5 s of the worktree's registration in .git/worktrees/<id>/).
Root cause
Claude Code's worktree creation appears to do:
git worktree add --no-checkout …- populate checkout with
core.hooksPath=/dev/nullin effect (hooks disabled during setup) - write the worktree's
config.worktreewithcore.longpaths=trueand
core.hooksPath=<absolute path to the main .git\hooks>
Step 2 is the problem on Windows: Git itself special-cases /dev/null, but git-lfs is a Go
binary and filepath.IsAbs("/dev/null") is false on Windows (no drive letter), so when the
checkout's LFS smudge spawns git-lfs filter-process, its hook auto-install resolves the
hooks dir relative to the worktree root and writes the four stubs into dev\null\.
Reproducible outside Claude Code with just git config core.hooksPath /dev/null +git lfs update --force in any repo — reported to git-lfs as git-lfs/git-lfs#6307.
So: any Windows user + any repo with LFS-tracked files ⇒ every isolation worktree is born
with untracked dev\null\* litter.
Suggested fix
Use a Windows-safe value to disable hooks during the populate checkout — e.g. an absolute
path to an empty or nonexistent directory inside the worktree's private gitdir
(.git/worktrees/<id>/hooks-disabled). Both git and git-lfs resolve absolute paths
correctly, and any stray LFS auto-install then lands harmlessly outside the working tree.
Avoid NUL/NUL:: per git-lfs's own FAQ that makes LFS hook installation fail, which
could break the checkout.
Workaround status
No user-facing knob changes the disable value, and no post-creation lifecycle hook exists to
clean up (WorktreeCreate replaces creation wholesale; PostWorktreeCreate is only a
feature request, #27744). Current workaround: a guard block prepended to the real LFS hooks
in .git\hooks that deletes the mis-installed dev/null stubs the first time any hook
fires in a worktree.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗