Git hooks are scripts that Git executes before or after events such as commit, push, and receive. They're stored in the .git/hooks
directory of a Git repository. By default, this directory contains sample scripts for various hooks with a .sample
extension.
To activate a hook, you must remove the .sample
extension and ensure the file is executable. These hooks allow you to enforce project policies, and integrate with CI/CD pipelines and other deployment strategies. This guide dives covers the essentials of Git hooks, providing detailed examples and explanations along the way.
Types of Git Hooks
There are two main types of Git hooks:
- Client-Side Hooks: These are triggered by operations such as committing and merging on a local machine. Examples include
pre-commit
,commit-msg
,pre-push
, etc. - Server-Side Hooks: These hooks run on the server, typically where your repository is hosted. Examples include
pre-receive
,update
,post-receive
, etc.
Pre-commit hook
A pre-commit
hook is run before a commit is finalized. It's commonly used to perform checks like linting, ensuring code standards, or running tests.
Example: To enforce code style checks before a commit is made, you can create a pre-commit
script:
Navigate to your repository's
.git/hooks
directory.Create a file named
pre-commit
(no extension).Add a script that runs a linter or code style checker. For a Python project, you might use
flake8
:Terminal#!/bin/shflake8 .Make the script executable:
chmod +x pre-commit
.
Now, every time you commit, flake8
will check your code for style issues.
Post-receive hook on the server
A post-receive
hook runs on the server after a push has been accepted. It's useful for deploying code or sending notifications.
Example: Automatically deploy your code when pushed to the main branch:
On the server hosting your Git repository, navigate to the repository's
hooks
directory.Create a
post-receive
file with the following script:Terminal#!/bin/shwhile read oldrev newrev refnamedoif [ "$refname" = "refs/heads/main" ]; then# Deploy code to productionecho "Deploying to production..."# Add deployment commands herefidoneMake it executable:
chmod +x post-receive
.
This hook checks if the push is to the main branch and executes deployment commands if true.
Managing hooks
Git hooks location
Hooks are stored in the .git/hooks
directory within your local repository. This makes them local to the repository and not versioned, meaning they don't get pushed to remote repositories.
Adding Hooks to a Repository
To share hooks with a team or integrate them into a project repository, you can:
- Create a directory (e.g.,
git_hooks/
) at the root of your repository. - Add your hook scripts to this directory.
- Use a setup script or documentation to instruct team members to symlink or copy these hooks into their
.git/hooks
directory. One tool that is great for this is husky.
Bypassing hooks
Sometimes, you might need to bypass a hook (e.g., a pre-commit hook) temporarily. You can do this by adding the --no-verify
option to your Git command:
git commit --no-verify -m "Your commit message"
This will skip all the Git hooks you have configured in your repository.
Best practices
- Version control your hooks: While hooks themselves don’t get pushed, storing their code in a separate directory within your repository ensures they are backed up and version-controlled.
- Document your hooks: Ensure that any hooks used within a project are well documented, so team members understand their purpose and how they work.
For more reading on Git hooks, see the official documentation.