-
Notifications
You must be signed in to change notification settings - Fork 119
Description
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
.gitignorebut not by root - Compare
VCS_STATUS_NUM_UNTRACKEDwithgit 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 repoExpected 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().