What are Git Hooks?

Git hooks are scripts that Git executes automatically before or after certain events, such as commit, push, and receive. They are a built-in feature of Git that allows you to customize its behavior and automate tasks in your workflow.

Hooks are stored in the .git/hooks directory of every Git repository. When you initialize a repository, Git populates this directory with several example scripts.

Problem Scenario

You want to enforce a certain standard for your project. For example, you want to ensure that:

  • All code is linted before it gets committed.
  • Commit messages follow a specific format.
  • Tests are run before pushing code to a remote repository.

Manually remembering to do these things is error-prone. Git hooks can automate this for you.

Solution

1. Locate the Hooks Directory

Navigate to the hooks directory within your Git repository:

cd .git/hooks
ls

You will see a list of sample hook files, such as:

  • pre-commit.sample
  • prepare-commit-msg.sample
  • commit-msg.sample
  • post-commit.sample
  • pre-push.sample

2. Create a Hook

To enable a hook, you need to create a file in the .git/hooks directory with the correct name and no extension. For example, to create a pre-commit hook, you would create a file named pre-commit.

Letโ€™s create a simple pre-commit hook that runs a linter.

  1. Rename or copy the sample file:
    cp pre-commit.sample pre-commit
    
  2. Make the script executable:
    chmod +x pre-commit
    
  3. Open the pre-commit file in an editor and add your script. It can be a shell script, or you can use other scripting languages like Python or Ruby.

Here is a simple shell script example that runs a linter on staged files:

#!/bin/sh

echo "Running linter before commit..."

# Run your linter command. For example, for a JavaScript project:
npm run lint

# If the linter fails, it will exit with a non-zero status,
# which will abort the commit.
if [ $? -ne 0 ]; then
  echo "Linting failed. Aborting commit."
  exit 1
fi

echo "Linting passed."
exit 0

Now, every time you run git commit, this script will execute. If the npm run lint command fails, the commit will be aborted.

Common Hooks

  • pre-commit: Runs before you type a commit message. Use it to inspect the snapshot thatโ€™s about to be committed. You can run tests or linting here.
  • commit-msg: Takes the commit message as an argument. Use it to validate the message against a required pattern or to automatically add information.
  • pre-push: Runs before you push code to a remote. Use it to run tests to ensure youโ€™re not pushing broken code.

Sharing Hooks

Git hooks are not cloned with the rest of your project. They are local to each developerโ€™s repository. This is a security measure to prevent malicious scripts from being run automatically.

To share hooks with your team, you can:

  1. Store the hooks in a directory within your project (e.g., scripts/hooks).
  2. Create a script that copies or symlinks them into the .git/hooks directory.
  3. Have developers run this setup script after cloning the repository.

Some tools, like Husky for JavaScript projects, can help manage and share Git hooks more easily.

Conclusion

Git hooks are a powerful mechanism for automating tasks and enforcing standards in your development workflow. By using hooks like pre-commit and pre-push, you can catch issues early and maintain a high level of code quality in your project.

Leave a comment