Make git status Faster with this One Weird Trick!

Many of us toil away in large git repos, spending countless seconds every day waiting for git status to return to us its precious information deep from within the bowels of git tree itself.

Much work has gone into git over the years to improve its performance in large repos. By my own measurements, on a fancy new M1 MacBook git status runs in a tolerable but sluggish 960ms at its fastest, but sometimes takes twice as long.

For a while I'd known about a way to make git status run quickly for times when you're feeling especially impatient—by telling it to ignore untracked (new to the repo) files with the with the --untracked-files=no flag, or --uno for short. With this flag we only have to wait 190ms for that sweet, sweet output. However, setting this as the default didn't work for me, as I was prone to forgetting that I'd created a new file and forget to add it into a commit, so I was stuck waiting a whole second still.

Git supports two other modes for the untracked files flag: normal and all, with normal being the default (surprise!).

Curious, I decided to compare the performance of all three modes in a large work repo, and got the following results:

git status -uno     190ms
git status -unormal 290ms
git status -uall    960ms

NB: benchmarks performed with hyperfine and don't represent worst case performance due to warmups, etc.

I was surprised by two things here. First that normal was only 100ms slower than the speedy no option, and second that the speed of git status -uall was the same as un-flagged git status... hold on, I thought, we're using the slow option as the default?! In this economy??

Yes, it turns out, by default everyone at my company's .gitconfig file contains the following:

[status]
  showUntrackedFiles = all

So by deleting the offending line (or changing it to normal), we can reap a 3.3x speed boost to git status without sacrificing knowing if we've got untracked changes to worry about.

What exactly is the difference in the output between normal and all though? Like its name implies, all shows all untracked files, with their full paths, while normal will just show the directories containing any changed files but not the files themselves. Sounds like an acceptable tradeoff to me.

Tell your friends—together we can take back entire minutes of lost productivity.

Bonus tip!

You can claw back another couple milliseconds but really just get pithier status output with the --short/status.short flag/config value.

The saga continues in part two.