Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check in a Bash script if my local Git repository has changes?

Tags:

git

People also ask

How do you check the status of your local git repository?

To check the status, open the git bash, and run the status command on your desired directory. It will run as follows: $ git status.

What git bash command will you use to check the current repository?

Use the git status command, to check the current state of the repository.


Using git status:

cd /git/directory
if [[ `git status --porcelain` ]]; then
  # Changes
else
  # No changes
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.


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
}

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

I had a similar problem, but I had to check for added files also. So I did the following:

cd /local/repo
RUN=0
git diff --no-ext-diff --quiet --exit-code || RUN=1
if [ $RUN = 0 ]; then
    RUN=`git ls-files --exclude-standard --others| wc -l`
fi

if [ $RUN = 0 ]; then
    exit 0
fi

git status is your friend

Change to the Git directory for git status to work:

cd c:/path/to/.git

Set a variable to set the work tree so you don't get 'This operation must be run in a work tree' error:

WORKTREE=c:/path/to/worktree

Capture the git status output in a Bash variable

Use --porcelain which guarantees to be in a standard format and parsable:

CHANGED=$(git --work-tree=${WORKTREE} status --porcelain)

If -n (not null), we have changes.

if [ -n "${CHANGED}" ]; then
  echo 'changed';

else
  echo 'not changed';
fi