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.