Stray `.git` directory created in non-repo cwd (e.g. $HOME) by the runtime-files exclude writer

Status Open
Reported on v2.1.217
Maintainer reply None cached
Activity 1 comment · opened Jul 26, 2026

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 only info/exclude, whose content starts with the # claude-code-runtime marker followed by **/.claude/... glob patterns (scheduled_tasks.lock, checkpoints/, worktrees/, mailbox/, …). No HEAD/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: true for ~ (current branch shows HEAD).
  • Other coding agents that use .git as 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.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗