[][src]Crate devx_pre_commit

devx-pre-commit provides utilities for creating git pre-commit hooks.

In particular, there are convenient APIs for

  • Efficiently running rustfmt on crates with staged rust source files
  • Installing the current binary to .git/hooks/pre-commit

This crate is meant to be used only in dev environment, preferably with cargo-xtask setup. By having something like the code bellow in xtask binary crate you will be able to run the following command to install the git pre-commit hook and never bother running cargo fmt manually again:

cargo xtask install-pre-commit-hook

ℹ️ Note: This assumes there is an alias in .cargo/config:

xtask = "run --package xtask --bin xtask --"

Example dev cli:

use devx_pre_commit::{PreCommitContext, locate_project_root};
use anyhow::Result;
use std::{ffi::OsStr, path::PathBuf};

fn run_hook() -> Result<()> {
    let mut ctx = PreCommitContext::from_git_diff(locate_project_root()?)?;

    // Optionally filter out the files you don't want to format
    ctx.retain_staged_files(|path| {
        path.components().all(|it| it.as_os_str() != OsStr::new("generated"))

    // Run `cargo fmt` against the crates with staged rust source files

    // Stage all the changes potenitally introduced by rustfmt
    // It is super-important to call this method at the end of the hook

fn main() -> Result<()> {
    if let Some(true) = std::env::args().next().map(|it| it.contains("pre-commit")) {
        return run_hook();
    match std::env::args().nth(1).expect("No args").as_str() {
        "install-pre-commit-hook" => {
        _ => {
            eprintln!("Hi, this is a dev cli, here are the available commands...");



Represents the API entrypoint of the git pre-commit hook. It carries the list of the staged files and the project root path. Note that staged file paths are all relative to the project root path.



Copies the current_exe file to ${project_root}/.git/hooks/pre-commit That's all you need to register a git pre-commit hook.


Searches for a project root dir, which is a directory that contains a .git dir as its direct child (it should also be the root of the project's Rust crate or cargo workspace).