Skip to content

status view: ls-files --others bypasses core.untrackedCache/fsmonitor, making pathless tig status 15-20x slower than git status in large repos #1448

Description

@hieuhoangtrung

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=true and core.fsmonitor=true, with the builtin daemon confirmed active via git 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 / 38b53b6, 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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions