Using Git Hooks to Automate Tasks

Run scripts before or after actions using Git hooks.


Introduction

Version control is at the heart of every software project. Git has become the de facto standard for tracking code changes, but did you know it can do much more than commit and push? Git Hooks are powerful tools that allow you to automate tasks in your workflow by running scripts before or after certain Git actions. In this article, you'll learn how Git hooks work, practical use cases, and how to set up your own.


What Are Git Hooks?

Git hooks are scripts that Git executes automatically in response to specific events in your repository. These events include actions like committing, merging, pushing, and more. Hooks live in the .git/hooks directory of your repository and can be written in any scripting language (typically shell scripts).

There are two types of hooks:

  • Client-side hooks: Run on your local machine on actions like committing or merging.
  • Server-side hooks: Run on a remote repository for events such as receiving a push.

Common Use Cases

Here are some tasks you can automate with Git hooks:

  • Code Formatting: Auto-format JavaScript, Python, or other code before committing.
  • Linting: Prevent commits or pushes if linting fails.
  • Running Tests: Ensure tests pass before merging code.
  • Validating Commit Messages: Enforce commit message guidelines.
  • Deployments: Trigger deployments after a successful push.

Setting Up Git Hooks

Let's look at the step-by-step process of adding hooks to a repository.

1. Locate the Hooks Directory

Inside your Git project, you'll find a .git/hooks directory with several sample scripts (like pre-commit.sample). These are examples; they're not active until renamed and made executable.

ls .git/hooks/

2. Create or Modify a Hook Script

Suppose you want to prevent commits if tests fail. You can use the pre-commit hook:

.git/hooks/pre-commit:

#!/bin/sh
echo "Running tests before commit..."
npm test
if [ $? -ne 0 ]; then
  echo "Tests failed. Commit aborted."
  exit 1
fi

This script:

  1. Runs your tests before every commit.
  2. Aborts the commit if tests fail (exit code other than 0).

3. Make the Script Executable

The script needs executable permissions:

chmod +x .git/hooks/pre-commit

4. Test It Out

Try to commit code. If your tests fail, the commit will be blocked, ensuring broken code doesn't slip in.


Popular Git Hooks and When They Run

Hook Name Runs Before/After Typical Usage
pre-commit Before commit Linting, testing, code formatting
commit-msg Before finishing commit Validate commit message format
pre-push Before push Run tests, check build
post-merge After merge Install dependencies, re-generate files

Tips for Working With Git Hooks

1. Sharing Hooks

Hooks aren't versioned with the repository by default. Tools like Husky (for Node.js projects) or Lefthook can help manage and distribute hooks across teams.

2. Use Portable Scripts

If your team uses different OSes, write hooks in portable languages (e.g., Node.js or Python) or test for compatibility.

3. Avoid Slow Hooks

Hooks run in the critical path of development. Keep them fast (especially pre-commit and pre-push) to avoid slowing down your workflow.


Example: Enforcing Conventional Commits

A common policy is to enforce conventional commit messages:

.git/hooks/commit-msg:

#!/bin/sh
if ! grep -qE "^(feat|fix|docs|style|refactor|test|chore)\: " "$1"; then
  echo "Commit message does not follow Conventional Commits (https://www.conventionalcommits.org/)"
  exit 1
fi

This hook ensures all commit messages start with a valid type, like feat:, fix:, etc.


Conclusion

Git hooks empower you to automate repetitive or critical tasks easily, enhancing the quality and consistency of your codebase. Try adding a simple pre-commit or commit-msg hook to your next project and see the difference. With proper use, Git hooks make your workflow safer, faster, and more efficient.


Ready to streamline your Git workflow? Start experimenting with hooks and unlock new productivity for your team!