Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I programmatically (in a shell script) determine whether or not there are changes?

Tags:

git

bash

I am trying to create a Bash script that knows if there are changes in current working directory. I know that

$ git status

returns a message like "nothing to commit". What I am trying to, is to define a variable to true or false. This boolean value will tell me if there are or not changes.

Obviously I am not an expert of bash scripts. I tried something like this,

there_are_changes=$(git status | grep nothin)
echo $there_are_changes

but it doesn't work as expected. What should I do?

like image 751
sensorario Avatar asked Feb 27 '15 18:02

sensorario


People also ask

How do you check if a variable is defined or not in shell script?

To find out if a bash variable is defined:-z ${PURGEIMAGE+z} ]] && echo "Set" || echo "Not defined" Return true if the variable is set on Bash version 4.2+ : [ -v $VAR ] && echo "Bash \$VAR NOT set"

How will you check whether a command exists and whether it is built in or not?

Use the command -v Command to Check if a Command Exists in Bash. The command -v is a built-in function in all POSIX systems and Bash. This function checks if a command exists as it returns the valid path for that command if it does exist and returns NULL if it does not.

What git command can you use to determine whether there are any changes on the local filesystem that have not been committed?

The "status" commmand helps you understand the current state of your local Working Copy. It will display any modifications in your local files that you haven't committed to the repository, yet.


2 Answers

The git-diff man page describes two options of relevance here:

--quiet
Disable all output of the program. Implies --exit-code.

and

--exit-code
Make the program exit with codes similar to diff(1). That is, it
exits with 1 if there were differences and 0 means no differences.

Therefore, a robust approach would be to run

git diff --quiet; nochanges=$?

The shell variable nochanges will be equal to 0 (i.e. true) if there are no changes, and 1 (i.e. false) otherwise.

You can then use the value of nochanges in conditional statements as follows:

if [ $nochanges -eq 0 ]; then
    # there are no changes
else
    # there are changes
fi

Alternatively, if you don't need to store the exit status in a variable, you can do:

if git diff --quiet; then
    # there are no changes
else
    # there are changes
fi

Since git diff is a porcelain Git command and you want to do things programmatically, you should probably use the plumbing Git command called git diff-index instead (which also has a --quiet flag, but which must be supplied a tree-ish argument):

if git diff-index --quiet HEAD; then
    # there are no changes
else
    # there are changes
fi

As pointed out in a comment below, the approach outlined above does not cover untracked files. To cover them as well, you can use the following instead:

if [ -z "$(git status --porcelain)" ]; then
    # there are no changes
else
    # there are changes
fi
like image 60
jub0bs Avatar answered Jan 06 '23 01:01

jub0bs


You can check if the variable is set by using the -n expression.

#!/bin/bash
CHANGESTOCOMMIT=$(git status | grep 'Changes to be com')
UNSTAGEDCHANGES=$(git status | grep 'Changes not staged')

# If there are staged changes:
if [ -n "$CHANGESTOCOMMIT" ]; then
    echo "Changes need to be committed"
fi
if [ -n "$UNSTAGEDCHANGES" ]; then
    echo "Changes made but not staged."
fi

Git tracks changed files that are both staged for committing, and also unstaged files, so your script might want to check both options (or not). The -n operator checks to see if the variable has been set - if it is empty it will return false.

An alternative is -z which returns True if it is empty (the logical opposite of -n. For a full list of conditional expressions please refer to the Bash Reference Manual.

like image 39
Aaron D Avatar answered Jan 06 '23 01:01

Aaron D