Skip to content

Simplify git dirty check using git status#410

Open
jesses-canva wants to merge 3 commits intopure-fish:masterfrom
jesses-canva:patch-1
Open

Simplify git dirty check using git status#410
jesses-canva wants to merge 3 commits intopure-fish:masterfrom
jesses-canva:patch-1

Conversation

@jesses-canva
Copy link

@jesses-canva jesses-canva commented Feb 24, 2026

In large repositories, checking for untracked files is very slow, so status.showUntrackedFiles=false is typically set to improve git status performance.

_pure_prompt_git_dirty doesn't use git status however, but three separate git commands to check for staged changes, unstaged changes and untracked files. The command for untracked files is git ls-files --others which doesn't respect status.showUntrackedFiles=false.

Instead we can check for non-empty output from git status --porcelain, which checks all three of these things in one command and respects status.showUntrackedFiles=false.

This reduces _pure_prompt_git_dirtry runtime from 9.3s to 0.8s on our repository.

In large repositories, checking for untracked files is very slow, so `status.showUntrackedFiles=false` is typically set to improve `git status` performance.

`_pure_prompt_git_dirty` doesn't use `git status` however, but three separate `git` commands to check for staged changes, unstaged changes and untracked files. The command for untracked files is `git ls-files --others` which doesn't respect `status.showUntrackedFiles=false`.

Instead we can check for non-empty output from `git status --porcelain`, which checks all three of these things in one command and respects `status.showUntrackedFiles=false`.

This reduces `_pure_prompt_git_dirtry` runtime from 9.3s to 0.8s on our repository.
Copy link
Member

@edouard-lopez edouard-lopez left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks,
the git commands were pretty old, and we haven't reviewed them in a long time.

Performance increase sound huge!
How does that impact smaller repos when used without status.showUntrackedFiles=false?

Could you update the doc by adding:
1.a quick reference to the Git section about big repo to send back to the Troubleshooting section, e.g. using Mkdocs admonition.
2. add an entry to the Troubleshooting component to add your remark about large repo

@jesses-canva
Copy link
Author

jesses-canva commented Mar 4, 2026

How does that impact smaller repos when used without status.showUntrackedFiles=false?

Using this repo as an example, it is a bit faster, probably just because its 1 command instead of (up to) 3, but the data is noisy:

$ git config --global status.showUntrackedFiles true

$ cat test.fish
#!/usr/bin/env fish
set --prepend fish_function_path (path dirname (status --current-filename))/functions
_pure_prompt_git_dirty

$ hyperfine \
  --warmup 10 \
  -n master \
  --prepare 'git checkout master' \
  'fish ./test.fish' \
  -n patch-1 \
  --prepare 'git checkout patch-1' \
  'fish ./test.fish'

Benchmark 1: master
  Time (mean ± σ):     253.5 ms ± 197.9 ms    [User: 52.4 ms, System: 60.4 ms]
  Range (min … max):   154.2 ms … 718.7 ms    14 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.

Benchmark 2: patch-1
  Time (mean ± σ):     163.3 ms ± 163.8 ms    [User: 40.2 ms, System: 46.0 ms]
  Range (min … max):   109.2 ms … 776.8 ms    16 runs

  Warning: Statistical outliers were detected. Consider re-running this benchmark on a quiet system without any interferences from other programs.

Summary
  patch-1 ran
    1.55 ± 1.97 times faster than master

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants