DEV Community

Joseph D. Marhee
Joseph D. Marhee

Posted on

Using pre-commit and post-update git hooks

Adding some additional processing to your git workflow is sometimes useful/cool/interesting, and the functionality provided by githooks make this fairly accessible to make use of. I typically make use of very few of these (in place of having things happen on the server-side — tests, etc.-that can be enabled externally or using server-side hooks) on the client-side, and adapt two included in .git/hooks/ by default, pre-commit and post-update, for, you guessed it, before commits are made, and after a set of commits are pushed.

In my capacity as an operations engineer, I make use of tools like Terraform often, which has the benefit of including a formatting tool and a validation tool — this is a good example of where a pre-commit hook can be useful — before I create a commit, I can validate the manifest and check formatting/style of the manifests being updated. I can do this by modifying, in my project root, .git/hooks/pre-commit.sample, and add something like this to check .tf files against these standards:

modified_files=$(git ls-files -m)
for f in modified_files
do
    if [-e "$f" ] && [[ $f == *.tf ]]; then
        terraform validate $(dirname $f)
        terraform fmt $f -check=true
        git add $f
    fi
done
Enter fullscreen mode Exit fullscreen mode

I’ve adapted my approach from James Turnbull’s pre-commit hook script to process this slightly differently, but also highlights that these are basically just a scriptable interface to manage git’s behavior.

To enable this hook, copy the file to .git/hooks/pre-commit (no .sample).

Let’s take a look at a more involved example in my post-update script. In my case, I am working on a Mac, so I’d like to make the most of this — maybe introduce some more visual cues for me to follow, so I want to use some Applescript as well.

In .git/hooks/post-update, I want to grab the hash and message of the last commit pushed, and the branch I pushed to:

COMMIT=$(git log -1 HEAD | head -n 1 | awk '{print $1}')
MESSAGE=$(git log --format=%B -n 1 $COMMIT | xargs echo )
BRANCH=$(git branch | grep \* | cut -d ' ' -f2)
Enter fullscreen mode Exit fullscreen mode

and to make this useful, I can see a summary of my latest push by adding this call to osascript:

/usr/bin/osascript <<EOF
display dialog "To $BRANCH:\n\n$MESSAGE\n\n\t($COMMIT)\n" with title "Git Push" buttons {"I meant to do that"} default button 1
Enter fullscreen mode Exit fullscreen mode

To have a pop-up dialog and just a reminder of what I did, so I stop to check my work one last time before moving on to my next task.

Discussion (0)