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]]
name = "PythonFormat"
cmd = ["black", "--check"]
filters = ["*.py"]
fix_cmd = ["black"]
[[pre_commit]]
name = "UnitTests"
cmd = ["./run_tests"]
pass_files = falseThat's it.
Install it with pip or pipx:
pip install iprecommitThen, initialize a pre-commit check in your git repository:
cd path/to/some/git/repo
iprecommit installiprecommit 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 runSome pre-commit issues can be fixed automatically:
iprecommit fixBy 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, andautofixandfail_fastset to true,iprecommitdoes 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
iprecommitdoesn't.
Husky is a pre-commit tool that is popular in the JavaScript ecosystem.
iprecommit has a few features that Husky doesn't:
iprecommitcan pass only changed files to your checks.iprecommitchecks can auto-fix problems (for instance, reformatting code).- Husky will stop at the first failing check, while
iprecommitwill run all checks (unlessfail_fastis set).
Set IPRECOMMIT_SKIP to a comma-separated list of checks to skip, e.g.:
$ IPRECOMMIT_SKIP="Check1,Check2" git commit -m '...'To persistently skip a check, set skip = true in the precommit.toml file.
[[pre_commit]]
name = "PythonFormat"
cmd = ["black", "--check"]
filters = ["*.py"]
fix_cmd = ["black"]nameis optional.- Changed files are passed to the command unless
pass_files = false. filtersis 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_cmdis present, theniprecommit fixwill unconditionally run the command.filtersstill 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"]nameandcmdare the only supported keys forcommit_msgchecks.cmdis 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"]nameandcmdare the only supported keys forpre_pushchecks.cmdis 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-formatchecks the format of the commit message.iprecommit-newline-at-eofchecks that each file ends with a newline.iprecommit-no-forbidden-stringschecks for forbidden strings.iprecommit-typoschecks for common typos.
- If you want to create your own template for
precommit.tomlto be used byiprecommit install, then set the environment variableIPRECOMMIT_TOML_TEMPLATEto the path to the file.