Recently I spent some time making improvements around deploying an application. Some of them are bash scripts automating some boring actions. All of them has one common part - should not be run if there are any changes (staged or not) in the local Git repository (working tree). Fortunately, it is simple to incorporate checks like this into scripts!

To get the information about staged (added with git add) and not staged files we will use git diff command. Without any parameters, it will give us detailed information of what changed. That is a bit too much than our needs, so we will use --stat flag to get only statistics - path to file and the number of lines added and removed:

# ~/repository> git diff --stat
 unstagedFile.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

For staged files we will use very similar command - it will be git diff --stat but with --cached flag:

# ~/repository> git diff --cached --stat
 stagedFile.txt | 1 +
 1 file changed, 1 insertion(+)

Both commands will return empty strings when no changes. We will use that information to show the message and stop (exit) script. In the end, script will look like this:

#!/bin/bash

# Fill up variables
STAGED_CHANGES=`git diff --cached --stat`
NOT_STAGED_CHANGES=`git diff --stat`

# Check if there are any staged but not committed changes
if [ ! -z "$STAGED_CHANGES" ]
then
  # Show message
  echo -e "You have staged, but not committed changes. Not releasing!"
  # And exit with non-zero code
  exit 1;
fi

# Check if there are any not staged
if [ ! -z "$NOT_STAGED_CHANGES" ]
then
  # Show message
  echo -e "You have not staged and not committed changes. Not releasing!"
  # And exit with non-zero code
  exit 1;
fi

## Anything else we need to do! ##

This script:

  • run commands mentioned above,
  • store results in variables,
  • if any of those variables are not empty - show the message and exit script with non-zero return value.

Why non-zero return value? Because by default 0 is treated as “everything was OK” and any other value means “error”. This allows to chain commands like doSomething && doMagic - in that case, doMagic will run only if doSomething return exited with 0.

Bonus stuff - we can make output red using some magic numbers which we can put in a script (in echo command):

#!/bin/bash
RED_START="\033[1;31m"
RED_END="\e[0m"

echo -e "Normal message!"
echo -e "${RED_START}Normal message but in RED!${RED_END}"

The result of the script above will look like this: The result of the colourful script

And that’s all folks! If you find this post useful - let me know! :-)