How can I check if I have any uncommitted changes in my git repository:
- Changes added to the index but not committed
- Untracked files
from a script?
git-status
seems to always return zero with git version 1.6.4.2.
How can I check if I have any uncommitted changes in my git repository:
from a script?
git-status
seems to always return zero with git version 1.6.4.2.
The key to reliably “scripting” Git is to use the ‘plumbing’ commands.
The developers take care when changing the plumbing commands to make sure they provide very stable interfaces (i.e. a given combination of repository state, stdin, command line options, arguments, etc. will produce the same output in all versions of Git where the command/option exists). New output variations in plumbing commands can be introduced via new options, but that can not introduce any problems for programs that have already been written against older versions (they would not be using the new options, since they did not exist (or at least were not used) at the time the script was written).
Unfortunately the ‘everyday’ Git commands are the ‘porcelain’ commands, so most Git users may not be familiar with with the plumbing commands. The distinction between porcelain and plumbing command is made in the main git manpage (see subsections titled High-level commands (porcelain) and Low-level commands (plumbing).
To find out about uncomitted changes, you will likely need
git diff-index
(compare index (and maybe tracked bits of working tree) against some other treeish (e.g.HEAD
)), maybegit diff-files
(compare working tree against index), and possiblygit ls-files
(list files; e.g. list untracked, unignored files).(Note that in the below commands,
HEAD --
is used instead ofHEAD
because otherwise the command fails if there is a file namedHEAD
.)To check whether a repository has staged changes (not yet committed) use this:
0
then there were no differences (1
means there were differences).To check whether a working tree has changes that could be staged:
git diff-index
(0
== no differences;1
== differences).To check whether the combination of the index and the tracked files in the working tree have changes with respect to
HEAD
:HEAD
). In this same situation, the two separate commands would both return reports of “differences present”.You also mentioned untracked files. You might mean “untracked and unignored”, or you might mean just plain “untracked” (including ignored files). Either way,
git ls-files
is the tool for the job:For “untracked” (will include ignored files, if present):
For “untracked and unignored”:
My first thought is to just check whether these commands have output:
0
then there are no untracked files. If it exits with1
then there are untracked files.There is a small chance that this will translate abnormal exits from
git ls-files
into “no untracked files” reports (both result in non-zero exits of the above command). A bit more robust version might look like this:git ls-files
to propagate out. In this case a non-zero exit could mean “there are untracked files” or it could mean an error occurred. If you want the “error” results combined with the “no untracked files” result instead, usetest -n "$u"
(where exit of0
means “some untracked files”, and non-zero means error or “no untracked files”).Another idea is to use
--error-unmatch
to cause a non-zero exit when there are no untracked files. This also runs the risk of conflating “no untracked files” (exit1
) with “an error occurred” (exit non-zero, but probably128
). But checking for0
vs.1
vs. non-zero exit codes is probably fairly robust:Any of the above
git ls-files
examples can take--exclude-standard
if you want to consider only untracked and unignored files.Had a look through a few of these answers... (and had various issues on *nix and windows, which was a requirement I had)... found the following worked well...
To check the exit code in *nix
To check the exit code in window$
Sourced from https://github.com/sindresorhus/pure/issues/115 Thanks to @paulirish on that post for sharing
One DIY possibility, updated to follow 0xfe's suggestion
As noted by Chris Johnsen, this only works on Git 1.7.0 or newer.
Here is the best, cleanest way. The selected answer didn't work for me for some reason, it didn't pick up changes staged that were new files that weren't committed.
This is a more shell friendly variation for finding out if any untracked files exist in the repository:
This doesn't fork a second process,
grep
, and doesn't need a check for if you are in a git repository or not. Which is handy for shell prompts, etc.You can also do
. It will append the word "-dirty" at the end if it detects a dirty working tree. According to
git-describe(1)
:. Caveat: untracked files are not considered "dirty", because, as the manpage states, it only cares about the working tree.