▸ Agent Skills
2 min read

Git Hooks

devenv has first-class integration for pre-commit via git-hooks.nix. This integration requires to have the git-hooks input the devenv.yaml file, as in the inputs page.

If this is not already in the file, add it using devenv inputs add git-hooks github:cachix/git-hooks.nix or insert it manually:

inputs:  git-hooks:    url: github:cachix/git-hooks.nix

devenv.yml snippet

Set up

We recommend a two-step approach for integrating your linters and formatters.

1) Make sure that commits are well-formatted at commit time

{ inputs, ... }:
{  git-hooks.hooks = {    # lint shell scripts    shellcheck.enable = true;    # execute example shell from Markdown files    mdsh.enable = true;    # format Python code    black.enable = true;
    # override a package with a different version    ormolu.enable = true;    ormolu.package = pkgs.haskellPackages.ormolu;
    # some hooks have more than one package, like clippy:    clippy.enable = true;    clippy.packageOverrides.cargo = pkgs.cargo;    clippy.packageOverrides.clippy = pkgs.clippy;    # some hooks provide settings    clippy.settings.allFeatures = true;  };}

devenv.nix

The full list can be found in the reference.

In action:

$ devenv shellBuilding shell ...Entering shell ...
pre-commit installed at .git/hooks/pre-commit

Terminal window

If you commit a Python or Markdown file or a script, these hooks will run at commit time.

2) Verify formatting in CI

Run devenv test.

See the list of all available hooks.

Managing the .pre-commit-config.yaml file

The .pre-commit-config.yaml file is a symlink to an autogenerated file in your devenv Nix store. It is not necessary to commit this file to your repository and it can safely be ignored. This file name will be added to your .gitignore file by default when you run devenv init.

Adding custom hooks

If you’d like to define your own hook you can do:

{  git-hooks.hooks.unit-tests = {    enable = true;
    # The name of the hook (appears on the report table):    name = "Unit tests";
    # The command to execute (mandatory):    entry = "make check";
    # The pattern of files to run on (default: "" (all))    # see also https://pre-commit.com/#hooks-files    files = "\\.(c|h)$";
    # List of file types to run on (default: [ "file" ] (all files))    # see also https://pre-commit.com/#filtering-files-with-types    # You probably only need to specify one of `files` or `types`:    types = [ "text" "c" ];
    # Exclude files that were matched by these patterns (default: [ ] (none)):    excludes = [ "irrelevant\\.c" ];
    # The language of the hook - tells pre-commit    # how to install the hook (default: "system")    # see also https://pre-commit.com/#supported-languages    language = "system";
    # Set this to false to not pass the changed files    # to the command (default: true):    pass_filenames = false;  };}

devenv.nix


Last updated Oct 08, 2026