Skip to content

git pre-commit Hooks

A very common use case for hooks in git is a "pre-commit" hook. This hook is used to verify the to-be-committed data before it is added to the repository.

One important note: hooks are not part of the repository itself. Everyone can install a hook on it's own checkout of a repository, but by default the hook is not there when you clone/checkout the repository. This avoids security problems by executing arbitrary code during "git commit", or any "git" operation.
Because of this implication it is common that developers install a hook from somewhere in the repository into the ".git/hooks" directory. And in addition, the server side (the repository) can run the same checks during "git push", to enforce the rules.

Hooks in git work in a simple way: whatever program or script is run as the hook has to set a return code. If the return code is "0", git proceeds. If it's not "0", git aborts the operation.


Back to the hook: the first problem is how to identify the to-be-committed files? "git diff" lists the files:

git diff --cached --name-only --diff-filter=ACM

The options:

  • --staged: lists all files which are stated for the next commit. --staged is an alias for --cached, both versions can be used.
  • --name-only: lists only the filenames, not the entire diff.
  • --diff-filter: selects what kind of files will be included in the diff.
    • A: Added files
    • C: Copied files
    • M: Modified files

The "git diff" above does not select "Renamed" or "Deleted" files. A renamed file might violate naming rules, in this case you have to include this option as well. And a deleted file is about to be removed from the repository, and most likely does not need to be checked.

Let's put this all together into a small shell script which runs as the git hook. In my example I want to enforce two things:

  1. No double spaces in the file
  2. No spaces at the end of the line

Here is the ".git/hooks/pre-commit" example:


set -e

echo "pre-flight checks:"

file_list=`git diff --cached --name-only --diff-filter=ACM`

while IFS= read -r file; do
    if [[ "$file" =~ ^content/post/* ]];
        echo "checking file: $file ..."
        if grep -q '  ' "$file";
            echo "Double spaces in file!"

        if egrep -q ' +$' "$file";
            echo "Spaces at end of line!"
done <<< "$file_list"

if [ "$exit_status" -eq "0" ];
    echo "Pre-flight check passed!"
    exit 0
    echo "There are some errors ..."
    exit 1

The first part identifies the changed files. The loop runs over all changed files, and checks them for the two conditons. The $exit_status variable is set by any error. Finally the last if-then-else part returns an error if there is any problem in the files.

  • Twitter
  • Bookmark git pre-commit Hooks at
  • Facebook
  • Google Bookmarks
  • FriendFeed
  • Digg git pre-commit Hooks
  • Bloglines git pre-commit Hooks
  • Technorati git pre-commit Hooks
  • Fark this: git pre-commit Hooks
  • Bookmark git pre-commit Hooks at YahooMyWeb
  • Bookmark git pre-commit Hooks at
  • Bookmark git pre-commit Hooks at
  • Bookmark git pre-commit Hooks at
  • Bookmark git pre-commit Hooks at
  • Bookmark git pre-commit Hooks at
  • Bookmark git pre-commit Hooks at blogmarks
  • Bookmark git pre-commit Hooks with wists
  • wong it!
  • Bookmark using any bookmark manager!
  • Stumble It!


No Trackbacks


Display comments as Linear | Threaded

Stephan on :

Hey Andreas, check out it's an open source tool built by Yelp for exactly this use case, and many more.
Comments ()

Andreas 'ads' Scherbaum on :

I know about this tool, but I find it oversized for the job. It can do too many things.
Comments ()

Sascha Henke on :

Hi, on this page is an example for a pre-commit hook, when you use Ansible Vault: I found it quite useful. Sascha
Comments ()

Add Comment

Enclosing asterisks marks text as bold (*word*), underscore are made via _word_.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.
Form options