Read Anthropic’s case study about Graphite Reviewer

Beginner's guide to Git hooks

Greg Foster
Greg Foster
Graphite software engineer


Note

This guide explains this concept in vanilla Git. For Graphite documentation, see our CLI docs.


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.

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.

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:

  1. Navigate to your repository's .git/hooks directory.

  2. Create a file named pre-commit (no extension).

  3. Add a script that runs a linter or code style checker. For a Python project, you might use flake8:

    Terminal
    #!/bin/sh
    flake8 .
  4. Make the script executable: chmod +x pre-commit.

Now, every time you commit, flake8 will check your code for style issues.

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:

  1. On the server hosting your Git repository, navigate to the repository's hooks directory.

  2. Create a post-receive file with the following script:

    Terminal
    #!/bin/sh
    while read oldrev newrev refname
    do
    if [ "$refname" = "refs/heads/main" ]; then
    # Deploy code to production
    echo "Deploying to production..."
    # Add deployment commands here
    fi
    done
  3. Make it executable: chmod +x post-receive.

This hook checks if the push is to the main branch and executes deployment commands if true.

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.

To share hooks with a team or integrate them into a project repository, you can:

  1. Create a directory (e.g., git_hooks/) at the root of your repository.
  2. Add your hook scripts to this directory.
  3. 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.

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:

Terminal
git commit --no-verify -m "Your commit message"

This will skip all the Git hooks you have configured in your repository.

  • 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.

Git inspired
Graphite's CLI and VS Code extension make working with Git effortless.
Learn more

Graphite
Git stacked on GitHub

Stacked pull requests are easier to read, easier to write, and easier to manage.
Teams that stack ship better software, faster.

Or install our CLI.
Product Screenshot 1
Product Screenshot 2