Frequently asked questions around Git and Version Control.
What are Git Hooks?
Git hooks allow you to run scripts (such as spelling checks, linters, or automated tests) before or after important events occur in the Git lifecycle, like committing, merging, and pushing.
At its most basic level, hooks can be useful for simple actions, such as enforcing naming conventions for commits or branches. However, since hook scripts can be customizable, any Git operation can be tweaked, enabling highly complex development workflows.
By running these custom scripts, the end goal is to assure consistency among teams, increase productivity, and save time; if your project is running a Continuous Integration pipeline, the number of failures can also be reduced by running some of the pipeline's tasks in the local machine.
Getting Started with Git Hooks
Hooks are a built-in feature in Git — you don't need to install anything. After initializing or cloning a repository, have a look at the hooks folder, which should be inside the hidden .git folder.
If we run the ls command, this is what we get:
$ cd .git/hooks$ ls
applypatch-msg.sample pre-applypatch.sample pre-rebase.sample
commit-msg.sample pre-commit.sample prepare-commit-msg.sample
post-update.sample pre-push.sample update.sample
All the pre- hooks run before the action takes place, while the post-hooks are used only for notifications. For example, a pre-commit hook could check the commit message for spelling errors, while a post-commit message could email team members to notify them that a new commit has been added to the repo.
Hooks are automatically copied from the templates/hooks folder of your global Git installation, and they are not checked in source control. There are more hooks available than just the ones listed here, but the goal is to provide some examples to get started.
By default, these example scripts are disabled — this can be altered by removing the desired hook's .sample extension.
There are client-side hooks (that will run on your local Git repository) and server-side hooks, that will live on your remote repository.
These are the most useful local hooks:
As for server-side, there are three hooks worth knowing (all of them are related to different stages of the git push process):
While hooks are usually shell commands, you can use whatever language you're most comfortable with, like Ruby or Python — just make sure you change the path of your interpreter.
To create a hook from scratch, create a new file (file name must match one of the hooks), write the code and make the file executable by running the following command (it will be ignored otherwise):
chmod +x prepare-commit-msg
That's it! From that point forward, the hook will be called.
There are times when you may need to skip the execution of hooks (e.g.: to bypass linters or security checks) and quickly get a commit out there. This is where the --no-verify option can come in handy.
Let's add a commit and bypass the pre-commit and commit-msg hooks:
$ git commit -m --no-verify "your commit message"
In this case, you could simply type -n for a shorter option. The following command would perform the same action:
$ git commit -mn "your commit message"
However, please note that -n won't always work. One example would be the git push command, where -n performs a dry run. In these cases, adding --no-verify is the only option available.
$ git push --no-verify
Bypassing Hooks in Tower
If you are using the Tower Git GUI, a "Skip Hooks" option will automatically be displayed in the "Commit Composing" window if a pre-commit hook is being used in the repository.
You can also skip the execution of hooks for push, pull, merge, rebase, and apply operations by accessing the list of additional options.