How can I check in a Bash script if my local Git repository has changes?
This works too:
if [ $(git status --porcelain | wc -l) -eq "0" ]; then
echo " ð¢ Git repo is clean."
else
echo " ð´ Git repo dirty. Quit."
exit 1
fi
Using git status
:
cd /git/directory
if [[ `git status --porcelain` ]]; then
# Changes
else
# No changes
fi
Although Jefromi's answer is good, I'm posting this just for reference.
From the Git source code there is a sh
script which includes the following.
require_clean_work_tree () {
git rev-parse --verify HEAD >/dev/null || exit 1
git update-index -q --ignore-submodules --refresh
err=0
if ! git diff-files --quiet --ignore-submodules
then
echo >&2 "Cannot $1: You have unstaged changes."
err=1
fi
if ! git diff-index --cached --quiet --ignore-submodules HEAD --
then
if [ $err = 0 ]
then
echo >&2 "Cannot $1: Your index contains uncommitted changes."
else
echo >&2 "Additionally, your index contains uncommitted changes."
fi
err=1
fi
if [ $err = 1 ]
then
test -n "$2" && echo >&2 "$2"
exit 1
fi
}
What you're doing will almost work: you should quote $CHANGED
in case it's empty, and -z
tests for empty, which means no changes. What you meant was:
if [ -n "$CHANGED" ]; then
VN="$VN-mod"
fi
A quote from Git's GIT-VERSION-GEN
:
git update-index -q --refresh
test -z "$(git diff-index --name-only HEAD --)" ||
VN="$VN-dirty"
It looks like you were copying that, but you just forgot that detail of quoting.
Of course, you could also just do this:
if git diff-index --quiet HEAD --; then
# No changes
else
# Changes
fi
Or if you only care about the "something has changed" case:
if ! git diff-index --quiet HEAD --; then
VN="$VN-mod"
fi
Using --quiet
has the benefit that Git can stop processing as soon as it encounters a single diff, so it may not have to check your entire work tree.