Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Benchmark results of the fastest way to check if a git branch is dirty

Tested against the WebKit git repo by entering the repo with 1 file dirty.


git diff --quiet --ignore-submodules HEAD # Will tell if there are any uncomitted changes, staged or not.
0.6 sec

git diff-index --quiet HEAD # Only tracked
2 sec

git diff --shortstat
8.2 sec

git status --porcelain
42 sec

zstyle ':vcs_info:*' check-for-changes true
50 sec

@millermedeiros

This comment has been minimized.

Copy link

@millermedeiros millermedeiros commented Mar 1, 2013

git diff --quiet --ignore-submodules HEAD doesn't show the untracked files so it might cause some undesired accidents.

@sindresorhus

This comment has been minimized.

Copy link
Owner Author

@sindresorhus sindresorhus commented Mar 4, 2013

True, but the only git status --percelain will do that, and it's sloooow.

@mathiasbynens

This comment has been minimized.

Copy link

@mathiasbynens mathiasbynens commented Apr 16, 2013

@sindresorhus Doesn’t git status without --porcelain do it too, kind of? That’s what I am using at the moment in my dotfiles: https://github.com/mathiasbynens/dotfiles/blob/9aecb166d67e0119472aceb8bba71b06256929d8/.bash_prompt#L46-L48 (credit to that code goes to @gf3; I stole it from him)

It might be slow, though.

@paulirish

This comment has been minimized.

Copy link

@paulirish paulirish commented Jun 30, 2013

Because it's related... this appears to be the fastest way to check the current branch (used by vcs_info and others)

git symbolic-ref -q HEAD | sed -e 's|^refs/heads/||'
@dideler

This comment has been minimized.

Copy link

@dideler dideler commented Sep 30, 2013

@paulirish My (non-scientific) tests show that not using the -q or --quiet option is the fastest, but then you'll probably want to redirect error messages to /dev/null/.

@gjasny

This comment has been minimized.

Copy link

@gjasny gjasny commented Dec 22, 2013

@paulirish Add the --short option and you can get rid of sed:

git symbolic-ref --short HEAD
@artjock

This comment has been minimized.

Copy link

@artjock artjock commented Feb 3, 2014

Did you try git status -suno? It's working faster for me and have the same limitations.
Full version is here: https://github.com/artjock/dotfiles/blob/master/bash/config#L20

@ericbn

This comment has been minimized.

Copy link

@ericbn ericbn commented Oct 14, 2016

Unless you want to take untracked files into account too. The best I've come up with is:

git diff-files --no-ext-diff --quiet || git diff-index --no-ext-diff --quiet --cached HEAD

This is the benchmark I got in a NFS filesystem with the WebKit repo clean:

Command Real time (secs)
git ls-files --other --exclude-standard (lists untracked files) 2.756
git status --porcelain (lists indexed, unindexed and untracked files) 2.313
git diff-index --no-ext-diff --quiet --cached HEAD (checks indexed files) 0.317
git diff-files --no-ext-diff --quiet (checks unindexed files) 0.022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.