status view: ls-files --others bypasses core.untrackedCache/fsmonitor, making pathless tig status 15-20x slower than git status in large repos
Summary
In a large monorepo (~563k tracked files, ~70 GB working tree), tig status without a pathspec takes 16-40 s to open. Essentially all of it is one command: git ls-files --others --exclude-standard.
The same information via git status --porcelain -uall costs ~1 s in that repo, because git status honours core.untrackedCache and core.fsmonitor. ls-files uses a separate traversal that ignores both, so the status view cannot benefit from either setting no matter how the repo is configured.
Environment
- tig 2.6.1
- git 2.50.1 (Apple Git-155)
- macOS 26.6.1, Apple Silicon
- Repo: 563,282 tracked files, ~70 GB working tree, many large gitignored directories
core.untrackedCache=trueandcore.fsmonitor=true, with the builtin daemon confirmed active viagit fsmonitor--daemon status
Measurements
Underlying git commands, warm cache, same repo and session:
| command | time |
|---|---|
git ls-files -z --others --exclude-standard |
16-21 s |
git status --porcelain -uall |
0.9-1.2 s |
git diff-files |
0.11 s |
git diff-index --cached HEAD |
0.12 s |
git update-index --refresh |
0.33 s |
Resulting time to open the view:
| command | time |
|---|---|
tig status |
16-40 s |
tig status confluence |
2.6 s |
tig status platform/packages/editor/editor-core |
0.54-0.60 s |
Absolute numbers drift between runs on this repo — the raw ls-files call itself measured anywhere from 15.9 s to 20.8 s across runs — but the ratio between the two approaches is consistent.
Relationship to #1424
#1424 / 38b53b68, released in 2.6.1, helps enormously here — thank you. Passing a pathspec takes the view sub-second, which is what makes tig usable in this repo at all.
This report is about the pathless case, which is still what a user types by default, and which no configuration currently improves.
Possible secondary issue
set status-show-untracked-files = no does not appear to avoid the ls-files --others call. Measured on 2.5.12 in the same repo: 17-21 s with it set, 16.4-16.6 s without it. I would have expected the untracked scan to be skipped entirely when untracked files are not going to be displayed. If that setting is only meant to filter output rather than skip collection, please disregard this part.
Suggestion
Populate the status view's untracked entries from git status --porcelain=v2 -z --untracked-files=all rather than git ls-files --others --exclude-standard, so the view inherits git's own untracked-cache and fsmonitor optimisations. Even as an opt-in setting for large repositories it would make a large difference.
Happy to test a patch against this repo and report numbers.
Source: jonas/tig