Bug: VCS_STATUS_NUM_UNTRACKED overcounts vs git status in repos with nested .gitignore files
Environment
- gitstatus v1.5.4
- macOS 15.3.1 (arm64)
- powerlevel10k (latest via oh-my-zsh)
POWERLEVEL9K_VCS_RECURSE_UNTRACKED_DIRS=0 (default)
Symptom
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).
$ print $VCS_STATUS_NUM_UNTRACKED
10
$ git ls-files --others --exclude-standard | wc -l
6
Repo structure
The repo has nested .gitignore files:
.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().
Bug:
VCS_STATUS_NUM_UNTRACKEDovercounts vsgit statusin repos with nested.gitignorefilesEnvironment
POWERLEVEL9K_VCS_RECURSE_UNTRACKED_DIRS=0(default)Symptom
VCS_STATUS_NUM_UNTRACKEDconsistently reports more untracked files thangit ls-files --others --exclude-standard. The overcount is stable acrossp10k reloadand full shell restarts (exec zsh).Repo structure
The repo has nested
.gitignorefiles:The
claude/directory contains runtime subdirectories (plugins/,cache/,teams/,logs/,tasks/) whose contents are gitignored byclaude/.gitignoreusing relative patterns (e.g.,plugins/,tasks/,logs/).Diagnosis
git ls-files --others --exclude-standard --directoryshows 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
.gitignorepatterns. Git CLI correctly suppresses these directories; libgit2 does not.Minimal reproduction
.gitignore.gitignorebut not by rootVCS_STATUS_NUM_UNTRACKEDwithgit ls-files --others --exclude-standard | wc -lExpected behavior
VCS_STATUS_NUM_UNTRACKEDshould matchgit 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().