What is a Git Hook?

Git hooks are script files that can be executed in response to specific events or operations. They can be classified into two distinct categories: client-side hooks and server-side hooks.

How to create a Git Hook

Git hooks are located within the .git/hooks directory. During the initialization of a repository using git init, a set of example hooks is generated, covering various types of hooks. These examples are suffixed with .sample, and in order to utilize them, the suffix must be removed. The provided examples are predominantly written as shell scripts, incorporating some Perl, but any appropriately named executable scripts can be used—be it Ruby, Python, or any other language you are familiar with.

Each hook possesses its own unique interpretation, necessitating a review of the provided examples or documentation to determine whether specific parameters are required, if a return value is expected, and other relevant specifications.

List of Git Hooks

  • applypatch.msg: Check the commit log taken by applypatch from an e-mail message. This script can modify the commit message. Exit with a non-zero status to stop the commit.
  • post-update: Prepare a packed repository for use over dump transports.
  • pre-applypatch: This script is executed before the applypatch hook.
  • prepare-commit-msg: This hook is called with git commit and it is used to prepare the commit message. It receives two parameters: the name of the file that has the changes and the description of the commit. If the script returns a non-zero status, the commit will be aborted
  • commit-msg: Called with one argument, the name of the file that has the commit message. This script can modify the commit message. Exit with a non-zero status to stop the commit.
  • pre-commit: This hooks is executed when you use git commit command. It takes no arguments but it is useful to pause the commit returning a non-zero status with a message. E.g: stop the commit if the code is not properly formatted or stop the commit if tests are failing.
  • post-commit: It runs once the git commit is finished. It does not take any argument and it is usually used to provide custom messages.
  • pre-merge-commit: This hook is executed when you are about to perform a git merge operation. It takes no arguments and should return a non-zero status to stop a merge.
  • pre-push: This hooks is executed when you perform a git push command. After checking the remote status, but before pushing anything. It takes two arguments: name of the remote branch and the URL to which the push will be done. If this script retun a non-zero status, it will stop the push.
  • pre-rebase: This hooks is executed before git rebase is started. It takes two arguments: the upstream the series was forked from and the branch being rebased (or empty when rebasing the current branch). If it returns a non-zero status, the rebase will be aborted.
  • post-checkout: Executed after a successful git checkout.

Check the complete list in the next url: Official list with all the git hooks

Setup Git Hooks with Rust

A wide range of freely available crates exists to enhance the implementation of git hooks in Rust projects. Personally, I have chosen to utilize the rusty-hook crate.

There are two methods for incorporating this crate into our project. The first approach involves adding it as a dev dependency in our Cargo.toml file. Upon building the project for the first time, it will be automatically initialized:

TOML
[dev-dependencies]
rusty-hook = "^0.11.2"

Or install and initialize it:

Bash
cargo install rusty-hook
rusty-hook init

How to use it

Once the crate is initialized we will be able to see new file named .rusty-hook.toml at the root of our project. This file is the only thing we need to work with rusty-hook.

The first time we open the file everything is already set up.

TOML
[hooks]
pre-commit = "cargo test"

[logging]
verbose = true

Under the [hooks] section, we have the ability to assign a custom script that will be executed for a specific git hook. The following example, extracted from a personal project, showcases a script that formats the code, runs clippy (a Rust linter), and executes all tests in the project before committing the staged changes.

TOML
[hooks]
pre-commit = "cargo fmt && git add . && cargo check && cargo test && cargo test --workspace -- --include-ignored --show-output && cargo clippy"
pre-push = "cargo fmt -- --check || cargo fmt && cargo fmt -- --check"

References:


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *