Stray `.git` directory created in non-repo cwd (e.g. $HOME) by the runtime-files exclude writer
Environment
- Claude Code 2.1.217 (npm install, Linux ELF via nvm), WSL2 Ubuntu
- First occurrence happened on an earlier (unrecorded) version; a second artifact appeared while 2.1.217 was in use
What happened
Running sessions with cwd in a directory that is not a git repository (in our case $HOME) occasionally leaves behind a stray .git directory:
- Occurrence 1:
~/.git/containing onlyinfo/exclude, whose content starts with the# claude-code-runtimemarker followed by**/.claude/...glob patterns (scheduled_tasks.lock,checkpoints/,worktrees/,mailbox/, …). NoHEAD/objects/refs— git itself does not recognize it as a repository. - Occurrence 2 (after deleting the first): a completely empty
~/.git/(zero entries). Its timestamp coincides with a session ending, which looks like the async write got interrupted between mkdir steps.
Suspected cause
Binary strings show a routine named ensureClaudeRuntimeFilesExcluded that appends the # claude-code-runtime block to .git/info/exclude. It appears to create .git/info/ recursively without first verifying that cwd is actually inside a git repository (no HEAD / rev-parse style check), and its catch handler only debug-logs, so the directory creation is silent.
Impact
A stray .git in $HOME makes git-aware tools misdetect the home directory as a repository/project root:
- Claude Code's own environment snapshot starts reporting
Is a git repository: truefor~(current branch showsHEAD). - Other coding agents that use
.gitas a project-root marker begin walking their rule/config discovery from~into every non-repo subdirectory.
Expected behavior
Never create .git. Only write .git/info/exclude when a valid repository already exists (an existing .git directory with HEAD, or a .git file pointing to a worktree gitdir).
Repro notes
Not deterministic on demand — the trigger is one of the runtime features that maintain the excluded files (checkpoints / scheduled tasks / worktrees). The # claude-code-runtime signature in occurrence 1 is unambiguous, and occurrence 2's bare directory matches an interrupted first-time write in a non-repo cwd.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗