Save more time with Git Hooks

Save more time with Git Hooks

If you need a refresher on what Git is and what it can do, you can go here

Whenever you create a new git project, you have the ability to use Git hooks to customize the internals of Git.

When you do

git init

you have initialized Git, but in doing so, it has created a hidden .git folder in your project’s local repo.

Hooks reside in the local .git/hooks directory of every Git repository. Git automatically populates this directory with example scripts when you initialize a repository. If you take a look inside .git/hooks, you’ll find the following files:

All of the files that we can modify to do almost whatever we like.

These files are not copied over if someone else clones the project. Because the files are local, it only affects you.

Lets look at the file called pre-commit.sample. Git hooks are just executable programs. This one is a shell script, but you could write one in Python or whatever scriptable programming language that you want as long as you point to the program i.e. the Python binary in the script.

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
 against=HEAD
else
 # Initial commit: diff against an empty tree object
 against=$(git hash-object -t tree /dev/null)
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --type=bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
 # Note that the use of brackets around a tr range is ok here, (it's
 # even required, for portability to Solaris 10's /usr/bin/tr), since
 # the square bracket bytes happen to fall in the designated range.
 test $(git diff --cached --name-only --diff-filter=A -z $against |
   LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
 cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
 exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

Lets go over several important lines.

#!/bin/sh

This is saying that the shell will run this script.

cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF

This will print out to the screen, an error message if allownonascii is false and you attempt to add a non ascii name.

When you are ready to use this file, change the filename from pre-commit.sample to just pre-commit.

mv .git/hooks/pre-commit.sample ./git/hooks/pre-commit

and then type in

chmod +x .git/hooks/pre-commit

Now it’s an executable and git will run it automatically. If you don’t want to run it anymore, you could remove it from being runnable by typing

chmod -x .git/hooks/pre-commit

There are many hooks, and lots of things that you can do. You can lock down the master branch, you could have a commit message template that users could modify.

You could even make branches follow structures like Jira tickets. You can even make it when you commit, it’ll do a build and run tests and you won’t be able to push until it passes. This can make your pipeline better as you normally won’t be able to break the build.

For more info on Git hooks, read the official documentation here

Fish hook silhouette from https://flyclipart.com/fish-hook-silhouette-free-fish-hook-tattoo-hook-clipart-867770"