A dead-simple tool to manage pre-commit hooks for Git.
iprecommit
runs shell commands and fails the hook if they fail. You can filter commands on glob patterns (e.g., *.py
for Python-only checks) and define fix commands (e.g., for auto-formatters).
[[pre_commit]]
cmd = ["black", "--check"]
filters = ["*.py"]
fix_cmd = ["black"]
[[pre_commit]]
cmd = ["./run_tests"]
pass_files = false
That's it.
Install it with pip
or pipx
:
pip install iprecommit
Then, initialize a pre-commit check in your git repository:
cd path/to/some/git/repo
iprecommit install
iprecommit install
will create a file called precommit.toml
to configure your pre-commit checks.
Now, whenever you run git commit
, the checks in precommit.toml
will be run automatically. You can also run the pre-commit checks manually:
iprecommit run
Some pre-commit issues can be fixed automatically:
iprecommit fix
By default, iprecommit run
and iprecommit fix
operate only on staged changes. To only consider unstaged changes as well, pass the --unstaged
flag. To run on every file in the repository (committed, unstaged, and staged), pass the --all
flag.
pre-commit is (as far as I can tell) the most widely-used library for pre-commit hook management.
I used pre-commit for a while. Here's why I created iprecommit
:
- I hated configuring my pre-commit checks in YAML.
- The colored output is hard to read with a dark theme, and this won't be fixed.
- I just wanted an intelligent way to run shell commands before
git commit
, not a "multi-language package manager". - With a custom template at
IPRECOMMIT_TOML_TEMPLATE
, andautofix
andfail_fast
set to true,iprecommit
does what I want and I rarely have to think about it.
Reasons you might prefer pre-commit:
- You like pre-commit's more extensive configuration options.
- You need one of the Git hooks that pre-commit supports and
iprecommit
doesn't.
Set skip = true
in the precommit.toml
file, or pass --skip <name>
to iprecommit run
.
[[pre_commit]]
name = "PythonFormat"
cmd = ["black", "--check"]
filters = ["*.py"]
fix_cmd = ["black"]
name
is optional.- Changed files are passed to the command unless
pass_files = false
. filters
is applied to the set of staged files. If the result is empty, the check is not run. Filters may be literal paths (example.py
), glob patterns (*.py
), or exclude patterns (!example.py
,!*.py
).- If
fix_cmd
is present, theniprecommit fix
will unconditionally run the command.filters
still applies as usual. - Commands run in the root of the Git repository by default. If you need the command to run elsewhere, set
working_dir
.
# commit-msg checks
[[commit_msg]]
name = "CommitMessageFormat"
cmd = ["iprecommit-commit-msg-format", "--max-line-length", "72"]
name
andcmd
are the only supported keys forcommit_msg
checks.cmd
is passed the name of a single file which holds the message's contents.
# pre-push checks (run on commit messages)
[[pre_push]]
name = "NoForbiddenStrings"
cmd = ["iprecommit-no-forbidden-strings", "--commits"]
name
andcmd
are the only supported keys forpre_push
checks.cmd
is passed a list of Git revisions to be pushed to the remote repository.
If the top-level autofix
option is set to true
in the TOML file, then when a fixable check fails, iprecommit run
will automatically invoke iprecommit fix
, and then re-run iprecommit run
after. This is useful if you have, e.g., auto-formatting checks that can fix themselves without human intervention.
These commands are designed to be used with iprecommit
, but they can also be used independently.
iprecommit-commit-msg-format
checks the format of the commit message.iprecommit-newline-at-eof
checks that each file ends with a newline.iprecommit-no-forbidden-strings
checks for forbidden strings.iprecommit-typos
checks for common typos.
- If you want to create your own template for
precommit.toml
to be used byiprecommit install
, then set the environment variableIPRECOMMIT_TOML_TEMPLATE
to the path to the file.