You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
VCS_STATUS_NUM_UNTRACKED overcounts in repos with nested .gitignore files #486
VCS_STATUS_NUM_UNTRACKED consistently reports more untracked files than git ls-files --others --exclude-standard. The overcount is stable across p10k reload and full shell restarts (exec zsh).
.gitignore # root (covers OS, Python, IDE, LaTeX patterns)
claude/.gitignore # Claude Code runtime state (plugins/, cache/, etc.)
codex/.gitignore # Codex CLI runtime state
The claude/ directory contains runtime subdirectories (plugins/, cache/, teams/, logs/, tasks/) whose contents are gitignored by claude/.gitignore using relative patterns (e.g., plugins/, tasks/, logs/).
Diagnosis
git ls-files --others --exclude-standard --directory shows zero unmatched directories — all phantom directories are properly gitignored. Yet gitstatus's libgit2 still counts ~4 extra entries.
The overcount appears to come from libgit2 treating directories as "untracked" even when all their contents are covered by nested .gitignore patterns. Git CLI correctly suppresses these directories; libgit2 does not.
Minimal reproduction
Create a repo with a subdirectory containing a .gitignore
Add files to the subdirectory that are ignored by the nested .gitignore but not by root
Compare VCS_STATUS_NUM_UNTRACKED with git ls-files --others --exclude-standard | wc -l
mkdir /tmp/gitstatus-repro &&cd /tmp/gitstatus-repro
git init
echo"*.log"> .gitignore
mkdir -p sub
echo"cache/"> sub/.gitignore
mkdir -p sub/cache
touch sub/cache/file1 sub/cache/file2 sub/cache/file3
git add .gitignore sub/.gitignore
git commit -m "init"# git sees 0 untracked; check if gitstatus agrees
git ls-files --others --exclude-standard | wc -l # expect: 0# Compare with VCS_STATUS_NUM_UNTRACKED after cd-ing into the repo
Expected behavior
VCS_STATUS_NUM_UNTRACKED should match git ls-files --others --exclude-standard | wc -l.
Notes
This may be an upstream libgit2 issue rather than gitstatus-specific, since gitstatus delegates gitignore processing to libgit2 via git_diff_index_to_workdir().
This can be reproduced with https://github.com/yulonglin/dotfiles — a dotfiles repo where claude/ (symlinked to ~/.claude/) has its own .gitignore with relative patterns for runtime state directories.
Related issues
This appears to be a known class of libgit2 bugs with nested .gitignore processing:
Activity
yulonglin commentedon Feb 18, 2026
Real-world reproduction
This can be reproduced with https://github.com/yulonglin/dotfiles — a dotfiles repo where
claude/(symlinked to~/.claude/) has its own.gitignorewith relative patterns for runtime state directories.Related issues
This appears to be a known class of libgit2 bugs with nested
.gitignoreprocessing:git status#59 —.gitignore resolution is inconsistent with git status(same root cause)libgit2 status fails to ignore untracked file.gitignore folder negation not working correctly.gitignore not in root folder is ignoredThe gitstatus author noted in #59 that "this part of libgit2 is riddled with bugs and is terribly inefficient."
test(nested-gitignore.sh): cover romkatv#486 and both romkatv#59 cases