Githook scripts are useful for identifying simple issues before submission tocode review. We run our hooks on every commit to automatically point outissues in code such as missing semicolons, trailing whitespace, and debugstatements. By pointing these issues out before code review, this allows acode reviewer to focus on the architecture of a change while not wasting timewith trivial style nitpicks.
As we created more libraries and projects we recognized that sharing ourpre-commit hooks across projects is painful. We copied and pasted unwieldybash scripts from project to project and had to manually change the hooks towork for different project structures.
Run pre-commit install to install pre-commit into your git hooks. pre-commitwill now run on every commit. Every time you clone a project using pre-commitrunning pre-commit install should always be the first thing you do.
The first time pre-commit runs on a file it will automatically download,install, and run the hook. Note that running a hook for the first time may beslow. For example: If the machine does not have node installed, pre-commitwill download and build a copy of node.
pre-commit currently supports hooks written inmany languages. As long as your git repo is aninstallable package (gem, npm, pypi, etc.) or exposes an executable, it can beused with pre-commit. Each git repo can support as many languages/hooks as youwant.
The hook repository must have a .pre-commit-channel folder and that foldermust contain the coursierapplication descriptorsfor the hook to install. For configuring coursier hooks, yourentry should correspond to an executable installed from therepository's .pre-commit-channel folder.
Support: coursier hooks are known to work on any system which has thecs or coursier package manager installed. The specific coursierapplications you install may depend on various versions of the JVM, consultthe hooks' documentation for clarification. It has been tested on linux.
Running Docker hooks requires a running Docker engine on your host. Forconfiguring Docker hooks, your entry should correspond to an executableinside the Docker container, and will be used to override the default containerentrypoint. Your Docker CMD will not run when pre-commit passes a file listas arguments to the run container command. Docker allows you to use anylanguage that's not supported by pre-commit as a builtin.
Support: docker hooks are known to work on any system which has a workingdocker executable. It has been tested on linux and macOS. Hooks that arerun via boot2docker are known to be unable to make modifications to files.
The entry specifies the docker tag to use. If an image has anENTRYPOINT defined, nothing special is needed to hook up the executable.If the container does not specify an ENTRYPOINT or you want to change theentrypoint you can specify it as well in your entry.
Hook repositories must contain a dotnet CLI tool which can be packed andinstalled as per thisexample. The entry should match an executable created by building therepository. Additional dependencies are not currently supported.
The hook repository must contain go source code. It will be installed viago install ./.... pre-commit will create an isolated GOPATH for each hookand the entry should match an executable which will get installed into theGOPATH's bin directory.
Hook repositories must have something that cpan supports, typicallyMakefile.PL or Build.PL, which it uses to install an executable touse in the entry definition for your hook. The repository will be installedvia cpan -T . (with the installed files stored in your pre-commit cache,not polluting other Perl installations).
This hook repository must have a renv.lock file that will be restored withrenv::restore() onhook installation. If the repository is an R package (i.e. has Type: Packagein DESCRIPTION), it is installed. The supported syntax in entry isRscript -e expression or Rscript path/relative/to/hook/root. TheR Startup process is skipped (emulating --vanilla), as all configurationshould be exposed via args for maximal transparency and portability.
Hook repositories must have a Cargo.toml file which produces at least onebinary (example),whose name should match the entry definition for your hook. The repo will beinstalled via cargo install --bins (with the binaries stored in yourpre-commit cache, not polluting your user-level Cargo installations).
System hooks provide a way to write hooks for system-level executables whichdon't have a supported language above (or have special environmentrequirements that don't allow them to run in isolation such as pylint).
Try the hooks in a repository, useful for developing new hooks.try-repo can also be used for testing out a repository before adding it toyour configuration. try-repo prints a configuration it generates based onthe remote hook repository before running the hooks.
By default, if you have existing hooks pre-commit install will install in amigration mode which runs both your existing hooks and hooks for pre-commit.To disable this behavior, pass -f / --overwrite to the install command.If you decide not to use pre-commit, pre-commit uninstall willrestore your hooks to the state prior to installation.
Not all hooks are perfect so sometimes you may need to skip execution of oneor more hooks. pre-commit solves this by querying a SKIP environmentvariable. The SKIP environment variable is a comma separated list of hookids. This allows you to skip a single hook instead of --no-verifying theentire commit.
Providers of hooks can select which git hooks they run on by setting thestages property in .pre-commit-hooks.yaml -- this canalso be overridden by setting stages in.pre-commit-config.yaml. If stages is not set in either of those placesthe default value will be pulled from the top-leveldefault_stages option (which defaults to allstages). By default, tools are enabled for every hook typethat pre-commit supports.
The manual stage (via stages: [manual]) is a special stage which will notbe automatically triggered by any git hook -- this is useful if you want toadd a tool which is not automatically run, but is run on demand usingpre-commit run --hook-stage manual [hookid].
If you are authoring a tool, it is usually a good idea to provide an appropriatestages property. For example a reasonable setting for a linter or codeformatter would be stages: [pre-commit, pre-merge-commit, pre-push, manual].
pre-commit is triggered before the commit is finalized to allow checks on thecode being committed. Running hooks on unstaged changes can lead to bothfalse-positives and false-negatives during committing. pre-commit only runson the staged contents of files by temporarily stashing the unstaged changeswhile running hooks.
prepare-commit-msg hooks will be passed a single filename -- this file maybe empty or it could contain the commit message from -m or from othertemplates. prepare-commit-msg hooks can modify the contents of this file tochange what will be committed. A hook may want to check for GIT_EDITOR=: asthis indicates that no editor will be launched. If a hook exits nonzero, thecommit will be aborted.
local hooks can use any language which supports additional_dependenciesor docker_image / fail / pygrep / script / system.This enables you to install things which previously would require a trivialmirror repository.
pre-commit init-templatedir can be used to set up a skeleton for git'sinit.templateDir option. This means that any newly cloned repository willautomatically have the hooks set up without the need to runpre-commit install.
If you want to match a file path that isn't included in a type when using anexisting hook you'll need to revert back to files only matching by overridingthe types setting. Here's an example of using check-json against non-jsonfiles:
If you find that your regular expression is becoming unwieldy due to a longlist of excluded / included things, you may find averbose regularexpression useful. One can enable this with yaml's multiline literals andthe (?x) regex flag.
pre-commit can also be used as a tool for continuous integration. Forinstance, adding pre-commit run --all-files as a CI step will ensureeverything stays in tip-top shape. To check only files which have changed,which may be faster, use something likepre-commit run --from-ref origin/HEAD --to-ref HEAD
pre-commit's cache requires to be served from a constant location between the different builds. This isn't the default when using k8s runnerson GitLab. In case you face the error InvalidManifestError, set builds_dir to something static e.g builds_dir = "/builds" in your [[runner]] config
tox is useful for configuring test / CI toolssuch as pre-commit. One feature of tox>=2 is it will clear environmentvariables such that tests are more reproducible. Under some conditions,pre-commit requires a few environment variables and so they must beallowed to be passed through.
Instead, pre-commit provides tools to make it easy to upgrade to thelatest versions with pre-commit autoupdate. Ifyou need the absolute latest version of a hook (instead of the latest taggedversion), pass the --bleeding-edge parameter to autoupdate.
pre-commit assumes that the value of rev is an immutable ref (such as atag or SHA) and will cache based on that. Using a branch name (or HEAD) forthe value of rev is not supported and will only represent the state ofthat mutable ref at the time of hook installation (and will NOT updateautomatically).
The Clang Compiler is an open-source compiler for the C family ofprogramming languages, aiming to be the best in class implementation ofthese languages. Clang builds on the LLVM optimizer and code generator,allowing it to provide high-quality optimization and code generationsupport for many targets. For more general information, please see theClang Web Site or the LLVM WebSite.
In addition to language specific features, Clang has a variety offeatures that depend on what CPU architecture or operating system isbeing compiled for. Please see the Target-Specific Features andLimitations section for more details.
3a8082e126