VCS_STATUS_NUM_UNTRACKED overcounts in repos with nested .gitignore files
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 1.8k
- Forks
- 134
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 1
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 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().
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimal reproduction in the issue and compare git ls-files --others --exclude-standard with VCS_STATUS_NUM_UNTRACKED. Then inspect gitstatus's use of libgit2 via git_diff_index_to_workdir(), checking how nested .gitignore files and ignored directories are counted. Done means the reported count matches Git's count for the reproduction.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, git
- Domain
- cli, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100