pip install pre-commit-exThis package is a drop-in replacement for pre-commit. It follows the upstream version number with a post-release suffix for changes applied on top — e.g. 4.6.1.post1, 4.6.1.post2 — so the base version always indicates which upstream release the fork is tracking.
It ships the same pre_commit module and pre-commit console script as upstream, so install it instead of pre-commit, not alongside it.
This fork tries to stay in sync with pre-commit/pre-commit, rebasing on top of new upstream releases where possible. All additions are intended to be backward compatible, with only additional functionality.
By default, pre-commit only allows invoking a hook with the arguments that have been preconfigured in the .pre-commit-config.yaml args: [...] field for that hook:
pre-commit run example-hookPassing different arguments to different invocations requires defining each permutation as a separate entry in .pre-commit-config.yaml with specific args: [...]. This doesn't support using hooks as general-purpose tools with dynamic arguments.
When --tool is used:
--all-filesis implied- The hook's
stagesmust includemanual(the default set already does) always_runis implied, so the hook runs even when no files match its filters- Arbitrary arguments can be passed after
--, replacing the configuredargs: [...] - Output is streamed live to the terminal
- Only the hook's exit code determines success — files modified by the hook are not treated as a failure
- A hook id missing from the resolved repository is a warning rather than a fatal error
A hook id is required, and -- arguments are only accepted together with --tool.
Usage:
pre-commit run <hook-id> --tool -- [arguments...]Example:
pre-commit run example-hook --tool -- --arg1 --arg2=4This invokes example-hook with --arg1 and --arg2=4 passed directly to the underlying tool, without needing a predefined entry for each argument combination.
--tool is only available on run, not on try-repo.
Tool-style hooks will usually want pass_filenames: false. With the default pass_filenames: true, --all-files means every file matching the hook's files/types/exclude filters — by default, every file in the repository — is appended after your -- arguments.
Suppresses the hook-name.....Success/Failed status line that is printed after a --tool or stream_output hook completes. Useful when capturing or piping the hook's output.
pre-commit run example-hook --tool --no-tool-status-message -- --arg1All user-facing subcommands now accept a --log-level option to control the verbosity of pre-commit's own status messages. This is independent of the hook's output, and is useful for suppressing [INFO] logging from pre-commit. For example when tracking a branch rev and wanting to suppress the messages notifying you of an update.
--log-level {DEBUG,INFO,WARNING,ERROR}
The default is INFO. Use WARNING or ERROR to suppress informational messages:
pre-commit run example-hook --log-level WARNINGHooks can opt in to live streaming of their output by setting stream_output: true in .pre-commit-hooks.yaml. Unlike buffered output, streamed output is written to the terminal as the hook runs rather than after it completes. Previously output would only be shown once the tool has completed.
- id: example-hook
name: Example Hook
entry: example-hook
language: python
stream_output: trueIt can also be set per-hook in .pre-commit-config.yaml to opt a third-party hook into streaming without changing its manifest.
A single repository can now contain multiple independent hooks, each with its own pyproject.toml (or equivalent package definition) located in a subdirectory. Set subdirectory in .pre-commit-hooks.yaml to point to the subdirectory that should be used as the package root for that hook.
- id: tool-a
name: Tool A
entry: tool-a
language: python
subdirectory: tool_a
- id: tool-b
name: Tool B
entry: tool-b
language: python
subdirectory: tool_bEach subdirectory should contain its own pyproject.toml defining the hook's dependencies and entry point. This allows for the same isolated environment for each tool, but the flexibility to keep multiple tools in the same repository — previously all tools in a repository installed into a single environment per language.
subdirectory only applies to cloned repositories; it is ignored for local and meta hooks.
A rev is classified as immutable (and therefore not subject to auto-resolution) if it is a hex commit hash (7+ characters) or a valid PEP 440 version string (e.g. 4.5.1, 1.0.0). Anything else — branch names, short aliases, non-PEP-440 tags — is treated as a mutable ref.
When a rev in .pre-commit-config.yaml is a mutable ref, this fork automatically resolves it to the corresponding commit hash at install time and re-resolves it on subsequent runs if the upstream ref has moved. A log message is printed when the resolved hash changes:
[INFO] Updating 'main': abc12345 -> def67890
This removes the need to run pre-commit autoupdate for repositories that you want to track by branch. pre-commit autoupdate can still be used to lock the rev to the current latest commit hash, but doing so will replace the branch name with a static hash, after which automatic tracking will no longer apply.
A framework for managing and maintaining multi-language pre-commit hooks.
For more information see: https://pre-commit.com/