PageSourceSearch

https://pre-commit.com/

html pre-commit.com collected 2026-10-02 02:20:19 UTC 147,100 bytes, 1,618 lines download raw bytes

1<!DOCTYPE html>
2<html>
3    <head>
4        <meta charset="utf-8">
5        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
7        <link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
8
9        <link rel="stylesheet" href="build/main_bs5.css">
10
11        <title>pre-commit</title>
12    </head>
13    <body data-bs-spy="scroll" data-bs-target="#content-navigation">
14        <nav class="navbar navbar-expand-md navbar-dark bg-primary">
15            <div class="container-md">
16                <a class="navbar-brand" href="/">
17                    <img src="logo.svg" width="55" height="55" alt="" loading="lazy">
18                </a>
19
20                <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbar" aria-controls="navbar" aria-expanded="false" >
21                    <span class="navbar-toggler-icon"></span>
22                </button>
23
24                <div class="collapse navbar-collapse" id="navbar">
25                    <ul class="navbar-nav">
26                        <li class="nav-item">
27                            <a class="nav-link active" href="index.html">Documentation</a>
28                        </li>
29                        <li class="nav-item">
30                            <a class="nav-link" href="hooks.html">Supported hooks</a>
31                        </li>
32                        <li class="nav-item">
33                            <a class="nav-link" href="https://github.com/pre-commit/demo-repo#readme">Demo</a>
34                        </li>
35                    </ul>
36
37                    <ul class="navbar-nav ms-auto">
38                        <li class="nav-item">
39                            <a href="https://github.com/pre-commit/pre-commit" role="button" class="btn btn-outline-info my-2 my-sm-0">Download on GitHub</a>
40                        </li>
41                    </ul>
42                </div>
43            </div>
44        </nav>
45
46        <header class="bg-light">
47            <div class="container-md py-4 py-lg-0">
48                <div class="d-flex justify-content-between align-items-center">
49                    <div>
50                        <h1 class="display-5 pb-3 text-secondary fw-bold">pre-commit</h1>
51                        <p class="lead text-white">
52                            A framework for managing and maintaining multi-language <span class="text-nowrap">pre-commit</span> hooks.
53                        </p>
54                        <div class="mb-3">
55                            <a href="https://github.com/pre-commit/pre-commit/actions/workflows/main.yml">
56                                <img src="https://github.com/pre-commit/pre-commit/actions/workflows/main.yml/badge.svg" alt="build status" style="max-width:100%;">
57                            </a>
58                            <a href="https://results.pre-commit.ci/latest/github/pre-commit/pre-commit/main">
59                                <img src="https://results.pre-commit.ci/badge/github/pre-commit/pre-commit/main.svg" alt="pre-commit.ci status" style="max-width:100%;">
60                            </a>
61                        </div>
62                        <div>
63                            <a class="github-button" href="https://github.com/pre-commit/pre-commit" data-show-count="true" aria-label="Star pre-commit/pre-commit on GitHub">Star</a>
64                            
64<script async defer src="https://buttons.github.io/buttons.js"></script>
64
65                        </div>
66                    </div>
67                    <img src="logo-top-shelf.png" alt="pre-commit logo" class="d-none d-lg-block" />
68                </div>
69            </div>
70        </header>
71
72        <main class="container-md my-4">
73            
74
75<div class="row">
76    <div class="col-sm-3 d-none d-lg-block">
77        <nav class="nav flex-column nav-pills sticky-top" aria-orientation="vertical" id="content-navigation">
78          <a class="nav-link active" href="#intro" role="tab">Introduction</a>
79          <a class="nav-link" href="#install" role="tab">Installation</a>
80          <a class="nav-link" href="#plugins" role="tab">Adding plugins</a>
81          <a class="nav-link" href="#usage" role="tab">Usage</a>
82          <a class="nav-link" href="#new-hooks" role="tab">Creating new hooks</a>
83          <a class="nav-link" href="#cli" role="tab">Command line interface</a>
84          <a class="nav-link" href="#advanced" role="tab">Advanced features</a>
85          <a class="nav-link" href="#contributing" role="tab">Contributing</a>
86        </nav>
87    </div>
88    <div class="col-lg-9 col-12">
89        <div id="intro">
90    <div class="page-header"><h1 id="introduction">    Introduction <small><a href="#introduction" class="text-decoration-none">¶</a></small></h1> </div>
91    <p>Git hook scripts are useful for identifying simple issues before submission to
92code review.  We run our hooks on every commit to automatically point out
93issues in code such as missing semicolons, trailing whitespace, and debug
94statements.  By pointing these issues out before code review, this allows a
95code reviewer to focus on the architecture of a change while not wasting time
96with trivial style nitpicks.</p>
97<p>As we created more libraries and projects we recognized that sharing our
98pre-commit hooks across projects is painful. We copied and pasted unwieldy
99bash scripts from project to project and had to manually change the hooks to
100work for different project structures.</p>
101<p>We believe that you should always use the best industry standard linters.
102Some of the best linters are written in languages that you do not use in your
103project or have installed on your machine. For example scss-lint is a linter
104for SCSS written in Ruby. If you’re writing a project in node you should be
105able to use scss-lint as a pre-commit hook without adding a Gemfile to your
106project or understanding how to get scss-lint installed.</p>
107<p>We built pre-commit to solve our hook issues. It is a multi-language package
108manager for pre-commit hooks. You specify a list of hooks you want and
109pre-commit manages the installation and execution of any hook written in any
110language before every commit. pre-commit is specifically designed to not
111require root access. If one of your developers doesn’t have node installed
112but modifies a JavaScript file, pre-commit automatically handles downloading
113and building node to run eslint without root.</p>
114
115</div>
116<div id="install">
117    <div class="page-header"><h1 id="installation">    Installation <small><a href="#installation" class="text-decoration-none">¶</a></small></h1> </div>
118    <p>Before you can run hooks, you need to have the pre-commit package manager
119installed.</p>
120<p>Using pip:</p>
121<div class="highlight bash"><pre><span></span>pip<span class="w"> </span>install<span class="w"> </span>pre-commit
122</pre></div>
123<p>In a python project, add the following to your requirements.txt (or
124requirements-dev.txt):</p>
125<div class="highlight"><pre><span></span>pre-commit
126</pre></div>
127<p>As a 0-dependency <a href="https://docs.python.org/3/library/zipapp.html">zipapp</a>:</p>
128<ul>
129<li>locate and download the <code>.pyz</code> file from the <a href="https://github.com/pre-commit/pre-commit/releases">github releases</a></li>
130<li>run <code>python pre-commit-#.#.#.pyz ...</code> in place of <code>pre-commit ...</code></li>
131</ul>
132<h2 id="quick-start">    Quick start <small><a href="#quick-start" class="text-decoration-none">¶</a></small></h2> <h3 id="1-install-pre-commit">    1. Install pre-commit <small><a href="#1-install-pre-commit" class="text-decoration-none">¶</a></small></h3> <ul>
133<li>follow the <a href="#install">install</a> instructions above</li>
134<li><code>pre-commit --version</code> should show you what version you're using</li>
135</ul>
136<div class="highlight pre-commit"><pre><span></span>$ pre-commit --version
137pre-commit 4.6.2
138</pre></div>
139<h3 id="2-add-a-pre-commit-configuration">    2. Add a pre-commit configuration <small><a href="#2-add-a-pre-commit-configuration" class="text-decoration-none">¶</a></small></h3> <ul>
140<li>create a file named <code>.pre-commit-config.yaml</code></li>
141<li>you can generate a very basic configuration using
142<a href="#pre-commit-sample-config"><code>pre-commit sample-config</code></a></li>
143<li>the full set of options for the configuration are listed <a href="#plugins">below</a></li>
144<li>this example uses a formatter for python code, however <code>pre-commit</code> works for
145any programming language</li>
146<li>other <a href="hooks.html">supported hooks</a> are available</li>
147</ul>
148<div class="highlight yaml"><pre><span></span><span class="nt">repos</span><span class="p">:</span>
149<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/pre-commit/pre-commit-hooks</span>
150<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v2.3.0</span>
151<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
152<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">
152check-yaml</span>
153<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">end-of-file-fixer</span>
154<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">trailing-whitespace</span>
155<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/psf/black</span>
156<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">22.10.0</span>
157<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
158<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">black</span>
159</pre></div>
160<h3 id="3-install-the-git-hook-scripts">    3. Install the git hook scripts <small><a href="#3-install-the-git-hook-scripts" class="text-decoration-none">¶</a></small></h3> <ul>
161<li>run <code>pre-commit install</code> to set up the git hook scripts</li>
162</ul>
163<div class="highlight console"><pre><span></span><span class="gp">$ </span>pre-commit<span class="w"> </span>install
164<span class="go">pre-commit installed at .git/hooks/pre-commit</span>
165</pre></div>
166<ul>
167<li>now <code>pre-commit</code> will run automatically on <code>git commit</code>!</li>
168</ul>
169<h3 id="4-optional-run-against-all-the-files">    4. (optional) Run against all the files <small><a href="#4-optional-run-against-all-the-files" class="text-decoration-none">¶</a></small></h3> <ul>
170<li>it's usually a good idea to run the hooks against all of the files when adding
171new hooks (usually <code>pre-commit</code> will only run on the changed files during
172git hooks)</li>
173</ul>
174<div class="highlight pre-commit"><pre><span></span>$ pre-commit run --all-files
175[INFO] Initializing environment for https://github.com/pre-commit/pre-commit-hooks.
176[INFO] Initializing environment for https://github.com/psf/black.
177[INFO] Installing environment for https://github.com/pre-commit/pre-commit-hooks.
178[INFO] Once installed this environment will be reused.
179[INFO] This may take a few minutes...
180[INFO] Installing environment for https://github.com/psf/black.
181[INFO] Once installed this environment will be reused.
182[INFO] This may take a few minutes...
183Check Yaml...............................................................<span class=" -Color -Color-BGGreen">Passed</span>
184Fix End of Files.........................................................<span class=" -Color -Color-BGGreen">Passed</span>
185Trim Trailing Whitespace.................................................<span class=" -Color -Color-BGRed">Failed</span>
186<span class=" -Color -Color-Faint">- hook id: trailing-whitespace</span>
187<span class=" -Color -Color-Faint">- exit code: 1</span>
188
189Files were modified by this hook. Additional output:
190
191Fixing sample.py
192
193black....................................................................<span class=" -Color -Color-BGGreen">Passed</span>
194</pre></div>
195<ul>
196<li>oops! looks like I had some trailing whitespace</li>
197<li>consider running that in <a href="#usage-in-continuous-integration">CI</a> too</li>
198</ul>
199
200</div>
201<div id="plugins">
202    <div class="page-header"><h1 id="adding-pre-commit-plugins-to-your-project">    Adding pre-commit plugins to your project <small><a href="#adding-pre-commit-plugins-to-your-project" class="text-decoration-none">¶</a></small></h1> </div>
203    <p>Once you have pre-commit installed, adding pre-commit plugins to your project
204is done with the <code>.pre-commit-config.yaml</code> configuration file.</p>
205<p>Add a file called <code>.pre-commit-config.yaml</code> to the root of your project. The
206pre-commit config file describes what repositories and hooks are installed.</p>
207<h2 id="pre-commit-configyaml---top-level">    .pre-commit-config.yaml - top level <small><a href="#pre-commit-configyaml---top-level" class="text-decoration-none">¶</a></small></h2> <table class="table table-bordered"><tbody><tr><td><p><a id="top_level-repos" href="#top_level-repos"><code>repos</code></a></p>
208</td><td><p>A list of <a href="#pre-commit-configyaml---repos">repository mappings</a>.</p>
209</td></tr><tr><td><p><a id="top_level-default_install_hook_types" href="#top_level-default_install_hook_types"><code>default_install_hook_types</code></a></p>
210</td><td><p>(optional: default <code>[pre-commit]</code>) a list of <code>--hook-type</code>s which will
211be used by default when running
212<a href="#pre-commit-install"><code>pre-commit install</code></a>.</p>
213</td></tr><tr><td><p><a id="top_level-default_language_version" href="#top_level-default_language_version"><code>default_language_version</code></a></p>
214</td><td><p>(optional: default <code>{}</code>) a mapping from language to the default
215<a href="#config-language_version"><code>language_version</code></a> that should be used for that language.  This will
216only override individual hooks that do not set <a href="#config-language_version"><code>language_version</code></a>.</p>
217<p>For example to use <code>python3.7</code> for <code>language: python</code> hooks:</p>
218<div class="highlight yaml"><pre><span></span><span class="nt">default_language_version</span><span class="p">:</span>
219<span class="w">    </span><span class="nt">python</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">python3.7</span>
220</pre></div>
221</td></tr><tr><td><p><a id="top_level-default_stages" href="#top_level-default_stages"><code>default_stages</code></a></p>
222</td><td><p>(optional: default (all stages)) a configuration-wide default for
223the <a href="#config-stages"><code>stages</code></a> property of hooks.  This will only override individual
224hooks that do not set <a href="#config-stages"><code>stages</code></a>.</p>
225<p>For example:</p>
226<div class="highlight yaml"><pre><span></span><span class="nt">default_stages</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">pre-commit</span><span class="p p-Indicator">
226,</span><span class="w"> </span><span class="nv">pre-push</span><span class="p p-Indicator">]</span>
227</pre></div>
228</td></tr><tr><td><p><a id="top_level-files" href="#top_level-files"><code>files</code></a></p>
229</td><td><p>(optional: default <code>''</code>) global file include pattern.</p>
230</td></tr><tr><td><p><a id="top_level-exclude" href="#top_level-exclude"><code>exclude</code></a></p>
231</td><td><p>(optional: default <code>^$</code>) global file exclude pattern.</p>
232</td></tr><tr><td><p><a id="top_level-fail_fast" href="#top_level-fail_fast"><code>fail_fast</code></a></p>
233</td><td><p>(optional: default <code>false</code>) set to <code>true</code> to have pre-commit stop
234running hooks after the first failure.</p>
235</td></tr><tr><td><p><a id="top_level-minimum_pre_commit_version" href="#top_level-minimum_pre_commit_version"><code>minimum_pre_commit_version</code></a></p>
236</td><td><p>(optional: default <code>'0'</code>) require a minimum version of pre-commit.</p>
237</td></tr></tbody></table><p>A sample top-level:</p>
238<div class="highlight yaml"><pre><span></span><span class="nt">exclude</span><span class="p">:</span><span class="w"> </span><span class="s">'^$'</span>
239<span class="nt">fail_fast</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">false</span>
240<span class="nt">repos</span><span class="p">:</span>
241<span class="p p-Indicator">-</span><span class="w">   </span><span class="l l-Scalar l-Scalar-Plain">...</span>
242</pre></div>
243<h2 id="pre-commit-configyaml---repos">    .pre-commit-config.yaml - repos <small><a href="#pre-commit-configyaml---repos" class="text-decoration-none">¶</a></small></h2> <p>The repository mapping tells pre-commit where to get the code for the hook
244from.</p>
245<table class="table table-bordered"><tbody><tr><td><p><a id="repos-repo" href="#repos-repo"><code>repo</code></a></p>
246</td><td><p>the repository url to <code>git clone</code> from
247or one of the special sentinel values:
248<a href="#repository-local-hooks"><code>local</code></a>,
249<a href="#meta-hooks"><code>meta</code></a>.</p>
250</td></tr><tr><td><p><a id="repos-rev" href="#repos-rev"><code>rev</code></a></p>
251</td><td><p>the revision or tag to clone at.</p>
252</td></tr><tr><td><p><a id="repos-hooks" href="#repos-hooks"><code>hooks</code></a></p>
253</td><td><p>A list of <a href="#pre-commit-configyaml---hooks">hook mappings</a>.</p>
254</td></tr></tbody></table><p>A sample repository:</p>
255<div class="highlight yaml"><pre><span></span><span class="nt">repos</span><span class="p">:</span>
256<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/pre-commit/pre-commit-hooks</span>
257<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1.2.3</span>
258<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
259<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="l l-Scalar l-Scalar-Plain">...</span>
260</pre></div>
261<h2 id="pre-commit-configyaml---hooks">    .pre-commit-config.yaml - hooks <small><a href="#pre-commit-configyaml---hooks" class="text-decoration-none">¶</a></small></h2> <p>The hook mapping configures which hook from the repository is used and allows
262for customization.  All optional keys will receive their default from the
263repository's configuration.</p>
264<table class="table table-bordered"><tbody><tr><td><p><a id="config-id" href="#config-id"><code>id</code></a></p>
265</td><td><p>which hook from the repository to use.</p>
266</td></tr><tr><td><p><a id="config-alias" href="#config-alias"><code>alias</code></a></p>
267</td><td><p>(optional) allows the hook to be referenced using an additional id when
268using <code>pre-commit run &lt;hookid&gt;</code>.</p>
269</td></tr><tr><td><p><a id="config-name" href="#config-name"><code>name</code></a></p>
270</td><td><p>(optional) override the name of the hook - shown during hook execution.</p>
271</td></tr><tr><td><p><a id="config-language_version" href="#config-language_version"><code>language_version</code></a></p>
272</td><td><p>(optional) override the language version for the
273hook.  See <a href="#overriding-language-version">Overriding Language Version</a>.</p>
274</td></tr><tr><td><p><a id="config-files" href="#config-files"><code>files</code></a></p>
275</td><td><p>(optional) override the default pattern for files to run on.</p>
276</td></tr><tr><td><p><a id="config-exclude" href="#config-exclude"><code>exclude</code></a></p>
277</td><td><p>(optional) file exclude pattern.</p>
278</td></tr><tr><td><p><a id="config-types" href="#config-types"><code>types</code></a></p>
279</td><td><p>(optional) override the default file types to run on (AND).  See
280<a href="#filtering-files-with-types">Filtering files with types</a>.</p>
281</td></tr><tr><td><p><a id="config-types_or" href="#config-types_or"><code>types_or</code></a></p>
282</td><td><p>(optional) override the default file types to run on (OR).  See
283<a href="#filtering-files-with-types">Filtering files with types</a>.</p>
284</td></tr><tr><td><p><a id="config-exclude_types" href="#config-exclude_types"><code>exclude_types</code></a></p>
285</td><td><p>(optional) file types to exclude.</p>
286</td></tr><tr><td><p><a id="config-args" href="#config-args"><code>args</code></a></p>
287</td><td><p>(optional) list of additional parameters to pass to the hook.</p>
288</td></tr><tr><td><p><a id="config-stages" href="#config-stages"><code>stages</code></a></p>
289</td><td><p>(optional) selects which git hook(s) to run for.
290See <a href="#confining-hooks-to-run-at-certain-stages">Confining hooks to run at certain stages</a>.</p>
291</td></tr><tr><td><p><a id="config-additional_dependencies" href="#config-additional_dependencies"><code>additional_dependencies</code></a></p>
292</td><td><p>(optional) a list of dependencies that will be installed in the
293environment where this hook gets run.  One useful application is to
294install plugins for hooks such as <code>eslint</code>.</p>
295</td></tr><tr><td><p><a id="config-always_run" href="#config-always_run"><code>
295always_run</code></a></p>
296</td><td><p>(optional) if <code>true</code>, this hook will run even if there are no matching
297files.</p>
298</td></tr><tr><td><p><a id="config-verbose" href="#config-verbose"><code>verbose</code></a></p>
299</td><td><p>(optional) if <code>true</code>, forces the output of the hook to be printed even when
300the hook passes.</p>
301</td></tr><tr><td><p><a id="config-log_file" href="#config-log_file"><code>log_file</code></a></p>
302</td><td><p>(optional) if present, the hook output will additionally be written to
303a file when the hook fails or <a href="#config-verbose">verbose</a> is <code>true</code>.</p>
304</td></tr></tbody></table><p>One example of a complete configuration:</p>
305<div class="highlight yaml"><pre><span></span><span class="nt">repos</span><span class="p">:</span>
306<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/pre-commit/pre-commit-hooks</span>
307<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1.2.3</span>
308<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
309<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">trailing-whitespace</span>
310</pre></div>
311<p>This configuration says to download the pre-commit-hooks project and run its
312trailing-whitespace hook.</p>
313<h2 id="updating-hooks-automatically">    Updating hooks automatically <small><a href="#updating-hooks-automatically" class="text-decoration-none">¶</a></small></h2> <p>You can update your hooks to the latest version automatically by running
314<a href="#pre-commit-autoupdate"><code>pre-commit autoupdate</code></a>.  By default, this will
315bring the hooks to the latest tag on the default branch.</p>
316
317</div>
318<div id="usage">
319    <div class="page-header"><h1 id="usage">    Usage <small><a href="#usage" class="text-decoration-none">¶</a></small></h1> </div>
320    <p>Run <code>pre-commit install</code> to install pre-commit into your git hooks. pre-commit
321will now run on every commit. Every time you clone a project using pre-commit
322running <code>pre-commit install</code> should always be the first thing you do.</p>
323<p>If you want to manually run all pre-commit hooks on a repository, run
324<code>pre-commit run --all-files</code>. To run individual hooks use
325<code>pre-commit run &lt;hook_id&gt;</code>.</p>
326<p>The first time pre-commit runs on a file it will automatically download,
327install, and run the hook. Note that running a hook for the first time may be
328slow. For example: If the machine does not have node installed, pre-commit
329will download and build a copy of node.</p>
330<div class="highlight pre-commit"><pre><span></span>$ pre-commit install
331pre-commit installed at /home/asottile/workspace/pytest/.git/hooks/pre-commit
332$ git commit -m "Add super awesome feature"
333black....................................................................<span class=" -Color -Color-BGGreen">Passed</span>
334blacken-docs.........................................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
335Trim Trailing Whitespace.................................................<span class=" -Color -Color-BGGreen">Passed</span>
336Fix End of Files.........................................................<span class=" -Color -Color-BGGreen">Passed</span>
337Check Yaml...........................................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
338Debug Statements (Python)................................................<span class=" -Color -Color-BGGreen">Passed</span>
339Flake8...................................................................<span class=" -Color -Color-BGGreen">Passed</span>
340Reorder python imports...................................................<span class=" -Color -Color-BGGreen">Passed</span>
341pyupgrade................................................................<span class=" -Color -Color-BGGreen">Passed</span>
342rst ``code`` is two backticks........................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
343rst..................................................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
344changelog filenames..................................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
345[main 146c6c2c] Add super awesome feature
346 1 file changed, 1 insertion(+)
347</pre></div>
348
349</div>
350<div id="new-hooks">
351    <div class="page-header"><h1 id="creating-new-hooks">    Creating new hooks <small><a href="#creating-new-hooks" class="text-decoration-none">¶</a></small></h1> </div>
352    <p>pre-commit currently supports hooks written in
353<a href="#supported-languages">many languages</a>. As long as your git repo is an
354installable package (gem, npm, pypi, etc.) or exposes an executable, it can be
355used with pre-commit. Each git repo can support as many languages/hooks as you
356want.</p>
357<p><em>new in 2.5.0</em>: <code>pre-commit</code> sets the <code>PRE_COMMIT=1</code> environment variable
358during hook execution.</p>
359<p>The hook must exit nonzero on failure or modify files.</p>
360<p>A git repo containing pre-commit plugins must contain a <code>.pre-commit-hooks.yaml</code>
361file that tells pre-commit:</p>
362<table class="table table-bordered"><tbody><tr><td><p><a id="hooks-id" href="#hooks-id"><code>id</code></a></p>
363</td><td><p>the id of the hook - used in pre-commit-config.yaml.</p>
364</td></tr><tr><td><p><a id="hooks-name" href="#hooks-name"><code>name</code></a></p>
365</td><td><p>the name of the hook - shown during hook execution.</p>
366</td></tr><tr><td><p><a id="hooks-entry" href="#hooks-entry"><code>entry</code></a></p>
367</td><td><p>the entry point - the executable to run.  <code>entry</code> can also contain
368arguments that will not be overridden such as <code>entry: autopep8 -i</code>.</p>
369</td></tr><tr><td><p><a id="hooks-language" href="#hooks-language"><code>language</code></a></p>
370</td><td><p>the language of the hook - tells pre-commit how to install the hook.</p>
371</td></tr><tr><td><p><a id="hooks-files" href="#hooks-files"><code>files</code></a></p>
372</td><td><p>(optional: default <code>''</code>) the pattern of files to run on.</p>
373</td></tr><tr><td><p><a id="hooks-exclude" href="#hooks-exclude"><code>exclude</code></a></p>
374</td><td><p>(optional: default <code>^$</code>)  exclude files that were matched by <a href="#hooks-files"><code>files</code></a>.</p>
375</td></tr><tr><td><p><a id="hooks-types" href="#hooks-types"><code>types</code></a></p>
376</td><td><p>(optional: default <code>[file]</code>)  list of file types to run on (AND).  See
377<a href="#filtering-files-with-types">Filtering files with types</a>.</p>
378</td></tr><tr><td><p><a id="hooks-types_or" href="#hooks-types_or"><code>types_or</code></a></p>
379</td><td><p>(optional: default <code>[]</code>)  list of file types to run on (OR).  See
380<a href="#filtering-files-with-types">Filtering files with types</a>.</p>
381</td></tr><tr><td><p><a id="hooks-exclude_types" href="#hooks-exclude_types"><code>exclude_types</code></a></p>
382</td><td><p>(optional: default <code>[]</code>)  the pattern of files to exclude.</p>
383</td></tr><tr><td><p><a id="hooks-always_run" href="#hooks-always_run"><code>always_run</code></a></p>
384</td><td><p>(optional: default <code>false</code>) if <code>true</code> this hook will run even if there
385are no matching files.</p>
386</td></tr><tr><td><p><a id="hooks-fail_fast" href="#hooks-fail_fast"><code>fail_fast</code></a></p>
387</td><td><p>(optional: default <code>false</code>) if <code>true</code> pre-commit will stop running
388hooks if this hook fails.</p>
389</td></tr><tr><td><p><a id="hooks-verbose" href="#hooks-verbose"><code>verbose</code></a></p>
390</td><td><p>(optional: default <code>false</code>) if <code>true</code>, forces the output of the hook to be printed even when
391the hook passes.</p>
392</td></tr><tr><td><p><a id="hooks-pass_filenames" href="#hooks-pass_filenames"><code>pass_filenames</code></a></p>
393</td><td><p>(optional: default <code>true</code>) if <code>false</code> no filenames will be passed to
394the hook.</p>
395</td></tr><tr><td><p><a id="hooks-require_serial" href="#hooks-require_serial"><code>require_serial</code></a></p>
396</td><td><p>(optional: default <code>false</code>) if <code>true</code> this hook will execute using a
397single process instead of in parallel.</p>
398</td></tr><tr><td><p><a id="hooks-description" href="#hooks-description"><code>description</code></a></p>
399</td><td><p>(optional: default <code>''</code>) description of the hook.  used for metadata
400purposes only.</p>
401</td></tr><tr><td><p><a id="hooks-language_version" href="#hooks-language_version"><code>language_version</code></a></p>
402</td><td><p>(optional: default <code>default</code>) see
403<a href="#overriding-language-version">Overriding language version</a>.</p>
404</td></tr><tr><td><p><a id="hooks-minimum_pre_commit_version" href="#hooks-minimum_pre_commit_version"><code>minimum_pre_commit_version</code></a></p>
405</td><td><p>(optional: default <code>'0'</code>) allows one to indicate a minimum
406compatible pre-commit version.</p>
407</td></tr><tr><td><p><a id="hooks-args" href="#hooks-args"><code>args</code></a></p>
408</td><td><p>(optional: default <code>[]</code>) list of additional parameters to pass to the hook.</p>
409</td></tr><tr><td><p><a id="hooks-stages" href="#hooks-stages"><code>stages</code></a></p>
410</td><td><p>(optional: default (all stages)) selects which git hook(s) to run for.
411See <a href="#confining-hooks-to-run-at-certain-stages">Confining hooks to run at certain stages</a>.</p>
412</td></tr></tbody></table><p>For example:</p>
413<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">trailing-whitespace</span>
414<span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Trim Trailing Whitespace</span>
415<span class="w">    </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">This hook trims trailing whitespace.</span>
416<span class="w">    </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">trailing-whitespace-fixer</span>
417<span class="w">    </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">python</span>
418<span class="w">    </span><span class="nt">types</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">text</span><span class="p p-Indicator">]</span>
419</pre></div>
420<h2 id="developing-hooks-interactively">    Developing hooks interactively <small><a href="#developing-hooks-interactively" class="text-decoration-none">¶</a></small></h2> <p>Since the <a href="#repos-repo"><code>repo</code></a> property of <code>.pre-commit-config.yaml</code> can refer to anything
421that <code>git clone ...</code> understands, it's often useful to point it at a local
422directory while developing hooks.</p>
423<p><a href="#pre-commit-try-repo"><code>pre-commit try-repo</code></a> streamlines this process by
424enabling a quick way to try out a repository.  Here's how one might work
425interactively:</p>
426<p><em>note</em>: you may need to provide <code>--commit-msg-filename</code> when using this
427command with hook types <code>prepare-commit-msg</code> and <code>commit-msg</code>.</p>
428<p>a commit is not necessary to <code>try-repo</code> on a local
429directory. <code>pre-commit</code> will clone any tracked uncommitted changes.</p>
430<div class="highlight pre-commit"><pre><span></span>~/work/hook-repo $ git checkout origin/main -b feature
431
432# ... make some changes
433
434# In another terminal or tab
435
436~/work/other-repo $ pre-commit try-repo ../hook-repo foo --verbose --all-files
437===============================================================================
438Using config:
439===============================================================================
440repos:
441-   repo: ../hook-repo
442    rev: 84f01ac09fcd8610824f9626a590b83cfae9bcbd
443    hooks:
444    -   id: foo
445===============================================================================
446[INFO] Initializing environment for ../hook-repo.
447Foo......................................................................<span class=" -Color -Color-BGGreen">Passed</span>
448<span class=" -Color -Color-Faint">- hook id: foo</span>
449<span class=" -Color -Color-Faint">- duration: 0.02s</span>
450
451Hello from foo hook!
452
453</pre></div>
454<h2 id="supported-languages">    Supported languages <small><a href="#supported-languages" class="text-decoration-none">¶</a></small></h2> <ul>
455<li><a href="#conda">conda</a></li>
456<li><a href="#coursier">coursier</a></li>
457<li><a href="#dart">dart</a></li>
458<li><a href="#docker">docker</a></li>
459<li><a href="#docker_image">docker_image</a></li>
460<li><a href="#dotnet">dotnet</a></li>
461<li><a href="#fail">fail</a></li>
462<li><a href="#golang">golang</a></li>
463<li><a href="#haskell">haskell</a></li>
464<li><a href="#julia">julia</a></li>
465<li><a href="#lua">lua</a></li>
466<li><a href="#node">node</a></li>
467<li><a href="#perl">perl</a></li>
468<li><a href="#python">python</a></li>
469<li><a href="#r">r</a></li>
470<li><a href="#ruby">ruby</a></li>
471<li><a href="#rust">rust</a></li>
472<li><a href="#swift">swift</a></li>
473<li><a href="#pygrep">pygrep</a></li>
474<li><a href="#unsupported">unsupported</a></li>
475<li><a href="#unsupported_script">unsupported_script</a></li>
476</ul>
477<h3 id="conda">    conda <small><a href="#conda" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must contain an <code>environment.yml</code> file which will be used
478via <code>conda env create --file environment.yml ...</code> to create the environment.</p>
479<p>The <code>conda</code> language also supports <a href="#config-additional_dependencies"><code>additional_dependencies</code></a>
480and will pass any of the values directly into <code>conda install</code>.  This language can therefore be
481used with <a href="#repository-local-hooks">local</a> hooks.</p>
482<p><code>mamba</code> or <code>micromamba</code> can be used to install instead via the
483<code>PRE_COMMIT_USE_MAMBA=1</code> or <code>PRE_COMMIT_USE_MICROMAMBA=1</code> environment
484variables.</p>
485<p><strong>Support:</strong> <code>conda</code> hooks work as long as there is a system-installed <code>conda</code>
486binary (such as <a href="https://docs.conda.io/en/latest/miniconda.html"><code>miniconda</code></a>).
487It has been tested on linux, macOS, and windows.</p>
488<h3 id="coursier">    coursier <small><a href="#coursier" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must have a <code>.pre-commit-channel</code> folder and that folder
489must contain the coursier
490<a href="https://get-coursier.io/docs/2.0.0-RC6-10/cli-install.html#application-descriptor-reference">application descriptors</a>
491for the hook to install. For configuring coursier hooks, your
492<a href="#hooks-entry"><code>entry</code></a> should correspond to an executable installed from the
493repository's <code>.pre-commit-channel</code> folder.</p>
494<p><strong>Support:</strong> <code>coursier</code> hooks are known to work on any system which has the
495<code>cs</code> or <code>coursier</code> package manager installed. The specific coursier
496applications you install may depend on various versions of the JVM, consult
497the hooks' documentation for clarification.  It has been tested on linux.</p>
498<p>pre-commit also supports the <code>coursier</code> naming of the package manager
499executable.</p>
500<p><em>new in 3.0.0</em>: <code>language: coursier</code> hooks now support <code>repo: local</code> and
501<code>additional_dependencies</code>.</p>
502<h3 id="dart">    dart <small><a href="#dart" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must have a <code>pubspec.yaml</code> -- this must contain an
503<code>executables</code> section which will list the binaries that will be available
504after installation.  Match the <a href="#hooks-entry"><code>entry</code></a> to an executable.</p>
505<p><code>pre-commit</code> will build each executable using <code>dart compile exe bin/{executable}.dart</code>.</p>
506<p><code>language: dart</code> also supports <a href="#config-additional_dependencies"><code>additional_dependencies</code></a>.
507to specify a version for a dependency, separate the package name by a <code>:</code>:</p>
508<div class="highlight yaml"><pre><span></span><span class="w">        </span><span class="nt">additional_dependencies</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="s">'hello_world_dart:1.0.0'</span><span class="p p-Indicator">]</span>
509</pre></div>
510<p><strong>Support:</strong> <code>dart</code> hooks are known to work on any system which has the <code>dart</code>
511sdk installed.  It has been tested on linux, macOS, and windows.</p>
512<h3 id="docker">    docker <small><a href="#docker" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must have a <code>Dockerfile</code>.  It will be installed via
513<code>docker build .</code>.</p>
514<p>Running Docker hooks requires a running Docker engine on your host.  For
515configuring Docker hooks, your <a href="#hooks-entry"><code>entry</code></a> should correspond to an executable
516inside the Docker container, and will be used to override the default container
517entrypoint. Your Docker <code>CMD</code> will not run when pre-commit passes a file list
518as arguments to the run container command. Docker allows you to use any
519language that's not supported by pre-commit as a builtin.</p>
520<p>pre-commit will automatically mount the repository source as a volume using
521<code>-v $PWD:/src:rw,Z</code> and set the working directory using <code>--workdir /src</code>.</p>
522<p><strong>Support:</strong> docker hooks are known to work on any system which has a working
523<code>docker</code> executable.  It has been tested on linux and macOS.  Hooks that are
524run via <code>boot2docker</code> are known to be unable to make modifications to files.</p>
525<p>See <a href="https://github.com/pre-commit/pre-commit-docker-flake8">this repository</a>
526for an example Docker-based hook.</p>
527<h3 id="docker_image">    docker_image <small><a href="#docker_image" class="text-decoration-none">¶</a></small></h3> <p>A more lightweight approach to <code>docker</code> hooks.  The <code>docker_image</code>
528&quot;language&quot; uses existing docker images to provide hook executables.</p>
529<p><code>docker_image</code> hooks can be conveniently configured as <a href="#repository-local-hooks">local</a>
530hooks.</p>
531<p>The <a href="#hooks-entry"><code>entry</code></a> specifies the docker tag to use.  If an image has an
532<code>ENTRYPOINT</code> defined, nothing special is needed to hook up the executable.
533If the container does not specify an <code>ENTRYPOINT</code> or you want to change the
534entrypoint you can specify it as well in your <a href="#hooks-entry"><code>entry</code></a>.</p>
535<p>For example:</p>
536<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">dockerfile-provides-entrypoint</span>
537<span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
538<span class="w">    </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">docker_image</span>
539<span class="w">    </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my.registry.example.com/docker-image-1:latest</span>
540<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">dockerfile-no-entrypoint-1</span>
541<span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
542<span class="w">    </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">docker_image</span>
543<span class="w">    </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">--entrypoint my-exe my.registry.example.com/docker-image-2:latest</span>
544<span class="c1"># Alternative equivalent solution</span>
545<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">dockerfile-no-entrypoint-2</span>
546<span class="w">    </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
547<span class="w">    </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">docker_image</span>
548<span class="w">    </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my.registry.example.com/docker-image-3:latest my-exe</span>
549</pre></div>
550<h3 id="dotnet">    dotnet <small><a href="#dotnet" class="text-decoration-none">¶</a></small></h3> <p>dotnet hooks are installed using the system installation of the dotnet CLI.</p>
551<p>Hook repositories must contain a dotnet CLI tool which can be <code>pack</code>ed and
552<code>install</code>
552ed as per <a href="https://docs.microsoft.com/en-us/dotnet/core/tools/global-tools-how-to-create">this</a>
553example. The <code>entry</code> should match an executable created by building the
554repository. Additional dependencies are not currently supported.</p>
555<p><strong>Support:</strong> dotnet hooks are known to work on any system which has the dotnet
556CLI installed.  It has been tested on linux and windows.</p>
557<h3 id="fail">    fail <small><a href="#fail" class="text-decoration-none">¶</a></small></h3> <p>A lightweight <a href="#hooks-language"><code>language</code></a> to forbid files by filename.  The <code>fail</code> language is
558especially useful for <a href="#repository-local-hooks">local</a> hooks.</p>
559<p>The <a href="#hooks-entry"><code>entry</code></a> will be printed when the hook fails.  It is suggested to provide
560a brief description for <a href="#hooks-name"><code>name</code></a> and more verbose fix instructions in <a href="#hooks-entry"><code>entry</code></a>.</p>
561<p>Here's an example which prevents any file except those ending with <code>.rst</code> from
562being added to the <code>changelog</code> directory:</p>
563<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">local</span>
564<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
565<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">changelogs-rst</span>
566<span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">changelogs must be rst</span>
567<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">changelog filenames must end in .rst</span>
568<span class="w">        </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">fail</span>
569<span class="w">        </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="s">'changelog/.*(?&lt;!\.rst)$'</span>
570</pre></div>
571<h3 id="golang">    golang <small><a href="#golang" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must contain go source code.  It will be installed via
572<code>go install ./...</code>.  pre-commit will create an isolated <code>GOPATH</code> for each hook
573and the <a href="#hooks-entry"><code>entry</code></a> should match an executable which will get installed into the
574<code>GOPATH</code>'s <code>bin</code> directory.</p>
575<p>This language supports <code>additional_dependencies</code> and will pass any of the values directly to <code>go install</code>. It can be used as a <code>repo: local</code> hook.</p>
576<p><em>changed in 2.17.0</em>: previously <code>go get ./...</code> was used</p>
577<p><em>new in 3.0.0</em>: pre-commit will bootstrap <code>go</code> if it is not present. <code>language: golang</code>
578also now supports <code>language_version</code></p>
579<p><strong>Support:</strong> golang hooks are known to work on any system which has go
580installed.  It has been tested on linux, macOS, and windows.</p>
581<h3 id="haskell">    haskell <small><a href="#haskell" class="text-decoration-none">¶</a></small></h3> <p><em>new in 3.4.0</em></p>
582<p>The hook repository must have one or more <code>*.cabal</code> files.  Once installed
583the <code>executable</code>s from these packages will be available to use with <code>entry</code>.</p>
584<p>This language supports <code>additional_dependencies</code> so it can be used as a
585<code>repo: local</code> hook.</p>
586<p><strong>Support:</strong> haskell hooks are known to work on any system which has <code>cabal</code>
587installed.  It has been tested on linux, macOS, and windows.</p>
588<h3 id="julia">    julia <small><a href="#julia" class="text-decoration-none">¶</a></small></h3> <p><em>new in 4.1.0</em></p>
589<p>For configuring julia hooks, your <a href="#hooks-entry"><code>entry</code></a> should be a path to a julia source
590file relative to the hook repository (optionally with arguments).</p>
591<p>Hooks run in an isolated package environment defined by a <code>Project.toml</code> file (optionally
592with a <code>Manifest.toml</code> file) in the hook repository. If no <code>Project.toml</code> file is found the
593hook is run in an empty environment.</p>
594<p>Julia hooks support <a href="#config-additional_dependencies"><code>additional_dependencies</code></a> which can
595be used to augment, or override, the existing environment in the hooks repository. This also
596means that julia can be used as a <code>repo: local</code> hook. <code>additional_dependencies</code> are passed
597to <code>pkg&gt; add</code> and should be specified using
598<a href="https://pkgdocs.julialang.org/v1/repl/#repl-add">Pkg REPL mode syntax</a>.</p>
599<p>Examples:</p>
600<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">foo-without-args</span>
601<span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
602<span class="w">  </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">julia</span>
603<span class="w">  </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">bin/foo.jl</span>
604<span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">bar-with-args</span>
605<span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
606<span class="w">  </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">julia</span>
607<span class="w">  </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">bin/bar.jl --arg1 --arg2</span>
608<span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">baz-with-extra-deps</span>
609<span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
610<span class="w">  </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">julia</span>
611<span class="w">  </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">
611bin/baz.jl</span>
612<span class="w">  </span><span class="nt">additional_dependencies</span><span class="p">:</span>
613<span class="w">   </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="s">'ExtraDepA@1'</span>
614<span class="w">   </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="s">'<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="13566b6761725776635153213d27">[email&#160;protected]</a>'</span>
615</pre></div>
616<p><strong>Support:</strong> julia hooks are known to work on any system which has <code>julia</code> installed.</p>
617<h3 id="lua">    lua <small><a href="#lua" class="text-decoration-none">¶</a></small></h3> <p>Lua hooks are installed with the version of Lua that is used by Luarocks.</p>
618<p><strong>Support:</strong> Lua hooks are known to work on any system which has Luarocks
619installed.  It has been tested on linux and macOS and <em>may</em> work on windows.</p>
620<h3 id="node">    node <small><a href="#node" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must have a <code>package.json</code>.  It will be installed via
621<code>npm install .</code>.  The installed package will provide an executable that will
622match the <a href="#hooks-entry"><code>entry</code></a> – usually through <code>bin</code> in package.json.</p>
623<p><strong>Support:</strong> node hooks work without any system-level dependencies.  It has
624been tested on linux, windows, and macOS and <em>may</em> work under cygwin.</p>
625<h3 id="perl">    perl <small><a href="#perl" class="text-decoration-none">¶</a></small></h3> <p>Perl hooks are installed using the system installation of
626<a href="https://perldoc.perl.org/cpan">cpan</a>, the CPAN package installer
627that comes with Perl.</p>
628<p>Hook repositories must have something that <code>cpan</code> supports, typically
629<code>Makefile.PL</code> or <code>Build.PL</code>, which it uses to install an executable to
630use in the <a href="#hooks-entry"><code>entry</code></a> definition for your hook. The repository will be installed
631via <code>cpan -T .</code> (with the installed files stored in your pre-commit cache,
632not polluting other Perl installations).</p>
633<p>When specifying <a href="#config-additional_dependencies"><code>additional_dependencies</code></a> for Perl, you can use any of the
634<a href="https://perldoc.perl.org/CPAN#get%2c-make%2c-test%2c-install%2c-clean-modules-or-distributions">install argument formats understood by <code>cpan</code></a>.</p>
635<p><strong>Support:</strong> Perl hooks currently require a pre-existing Perl installation,
636including the <code>cpan</code> tool in <code>PATH</code>.  It has been tested on linux, macOS, and
637Windows.</p>
638<h3 id="python">    python <small><a href="#python" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must be installable via <code>pip install .</code> (usually by either
639<code>setup.py</code> or <code>pyproject.toml</code>).  The installed package will provide an
640executable that will match the <a href="#hooks-entry"><code>entry</code></a> – usually through <code>console_scripts</code> or
641<code>scripts</code> in setup.py.</p>
642<p>This language also supports <code>additional_dependencies</code>
643so it can be used with <a href="#repository-local-hooks">local</a> hooks.
644The specified dependencies will be appended to the <code>pip install</code> command.</p>
645<p><strong>Support:</strong> python hooks work without any system-level dependencies.  It
646has been tested on linux, macOS, windows, and cygwin.</p>
647<h3 id="r">    r <small><a href="#r" class="text-decoration-none">¶</a></small></h3> <p>This hook repository must have a <code>renv.lock</code> file that will be restored with
648<a href="https://rstudio.github.io/renv/reference/restore.html"><code>renv::restore()</code></a> on
649hook installation. If the repository is an R package (i.e. has <code>Type: Package</code>
650in <code>DESCRIPTION</code>), it is installed. The supported syntax in <a href="#hooks-entry"><code>entry</code></a> is
651<code>Rscript -e {expression}</code> or <code>Rscript path/relative/to/hook/root</code>. The
652R Startup process is skipped (emulating <code>--vanilla</code>), as all configuration
653should be exposed via <a href="#hooks-args"><code>args</code></a> for maximal transparency and portability.</p>
654<p>When specifying <a href="#config-additional_dependencies"><code>additional_dependencies</code></a>
655for R, you can use any of the install argument formats understood by
656<a href="https://rstudio.github.io/renv/reference/install.html#examples"><code>renv::install()</code></a>.</p>
657<p><strong>Support:</strong> <code>r</code> hooks work as long as <a href="https://www.r-project.org"><code>R</code></a> is
658installed and on <code>PATH</code>. It has been tested on linux, macOS, and windows.</p>
659<h3 id="ruby">    ruby <small><a href="#ruby" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must have a <code>*.gemspec</code>.  It will be installed via
660<code>gem build *.gemspec &amp;&amp; gem install *.gem</code>.  The installed package will
661produce an executable that will match the <a href="#hooks-entry"><code>entry</code></a> – usually through
662<code>executables</code> in your gemspec.</p>
663<p><strong>Support:</strong> ruby hooks work without any system-level dependencies.  It has
664been tested on linux and macOS and <em>may</em> work under cygwin.</p>
665<h3 id="rust">    rust <small><a href="#rust" class="text-decoration-none">¶</a></small></h3> <p>Rust hooks are installed using <a href="https://github.com/rust-lang/cargo">Cargo</a>,
666Rust's official package manager.</p>
667<p>Hook repositories must have a <code>Cargo.toml</code> file which produces at least one
668binary (<a href="https://github.com/chriskuehl/example-rust-pre-commit-hook">example</a>),
669whose name should match the <a href="#hooks-entry"><code>entry</code></a> definition for your hook. The repo will be
670installed via <code>cargo install --bins</code> (with the binaries stored in your
671pre-commit cache, not polluting your user-level Cargo installations).</p>
672<p>When specifying <a href="#config-additional_dependencies"><code>additional_dependencies</code></a>
672 for Rust, you can use the syntax
673<code>{package_name}:{package_version}</code> to specify a new library dependency (used to
674build <em>your</em> hook repo), or the special syntax
675<code>cli:{package_name}:{package_version}</code> for a CLI dependency (built separately,
676with binaries made available for use by hooks).</p>
677<p>pre-commit will bootstrap <code>rust</code> if it is not present.
678<code>language: rust</code> also supports <code>language_version</code></p>
679<p><strong>Support:</strong> It has been tested on linux, Windows, and macOS.</p>
680<h3 id="swift">    swift <small><a href="#swift" class="text-decoration-none">¶</a></small></h3> <p>The hook repository must have a <code>Package.swift</code>.  It will be installed via
681<code>swift build -c release</code>.  The <a href="#hooks-entry"><code>entry</code></a> should match an executable created by
682building the repository.</p>
683<p><strong>Support:</strong> swift hooks are known to work on any system which has swift
684installed.  It has been tested on linux and macOS.</p>
685<h3 id="pygrep">    pygrep <small><a href="#pygrep" class="text-decoration-none">¶</a></small></h3> <p>A cross-platform python implementation of <code>grep</code> – pygrep hooks are a quick
686way to write a simple hook which prevents commits by file matching.  Specify
687the regex as the <a href="#hooks-entry"><code>entry</code></a>.  The <a href="#hooks-entry"><code>entry</code></a> may be any python
688<a href="#regular-expressions">regular expression</a>.  For case insensitive regexes you
689can apply the <code>(?i)</code> flag as the start of your entry, or use <code>args: [-i]</code>.</p>
690<p>For multiline matches, use <code>args: [--multiline]</code>.</p>
691<p>To require all files to match, use <code>args: [--negate]</code>.</p>
692<p><strong>Support:</strong> pygrep hooks are supported on all platforms which pre-commit runs
693on.</p>
694<h3 id="unsupported">    unsupported <small><a href="#unsupported" class="text-decoration-none">¶</a></small></h3> <p><a name="system"></a>
695<em>new in 4.4.0</em>: previously <code>language: system</code>.  the alias will be removed in a
696future version</p>
697<p>System hooks provide a way to write hooks for system-level executables which
698don't have a supported language above (or have special environment
699requirements that don't allow them to run in isolation such as pylint).</p>
700<p>This hook type will not be given a virtual environment to work with – if it
701needs additional dependencies the consumer must install them manually.</p>
702<h3 id="unsupported_script">    unsupported_script <small><a href="#unsupported_script" class="text-decoration-none">¶</a></small></h3> <p><a name="script"></a>
703<em>new in 4.4.0</em>: previously <code>language: script</code>.  the alias will be removed in a
704future version</p>
705<p>Script hooks provide a way to write simple scripts which validate files. The
706<a href="#hooks-entry"><code>entry</code></a> should be a path relative to the root of the hook repository.</p>
707<p>This hook type will not be given a virtual environment to work with – if it
708needs additional dependencies the consumer must install them manually.</p>
709
710</div>
711<div id="cli">
712    <div class="page-header"><h1 id="command-line-interface">    Command line interface <small><a href="#command-line-interface" class="text-decoration-none">¶</a></small></h1> </div>
713    <p>All pre-commit commands take the following options:</p>
714<ul>
715<li><code>--color {auto,always,never}</code>: whether to use color in output.
716Defaults to <code>auto</code>.  can be overridden by using
717<code>PRE_COMMIT_COLOR={auto,always,never}</code> or disabled using <code>TERM=dumb</code>.</li>
718<li><code>-c CONFIG</code>, <code>--config CONFIG</code>: path to alternate config file</li>
719<li><code>-h</code>, <code>--help</code>: show help and available options.</li>
720</ul>
721<p><code>pre-commit</code> exits with specific codes:</p>
722<ul>
723<li><code>1</code>: a detected / expected error</li>
724<li><code>3</code>: an unexpected error</li>
725<li><code>130</code>: the process was interrupted by <code>^C</code></li>
726</ul>
727<h2 id="pre-commit-autoupdate">    pre-commit autoupdate [options] <small><a href="#pre-commit-autoupdate" class="text-decoration-none">¶</a></small></h2> <p>Auto-update pre-commit config to the latest repos' versions.</p>
728<p>Options:</p>
729<ul>
730<li><code>--bleeding-edge</code>: update to the bleeding edge of the default branch instead
731of the latest tagged version (the default behaviour).</li>
732<li><code>--freeze</code>: Store &quot;frozen&quot; hashes in <a href="#repos-rev"><code>rev</code></a> instead of tag names.</li>
733<li><code>--repo REPO</code>: Only update this repository. This option may be specified
734multiple times.</li>
735<li><code>-j</code> / <code>--jobs</code>: <em>new in 3.3.0</em> Number of threads to use (default: 1).</li>
736</ul>
737<p>Here are some sample invocations using this <code>.pre-commit-config.yaml</code>:</p>
738<div class="highlight yaml"><pre><span></span><span class="nt">repos</span><span class="p">:</span>
739<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/pre-commit/pre-commit-hooks</span>
740<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v2.1.0</span>
741<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
742<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">trailing-whitespace</span>
743<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/asottile/pyupgrade</span>
744<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1.25.0</span>
745<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
746<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pyupgrade</span>
747<span class="w">        </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">--py36-plus</span><span class="p p-Indicator">]</span>
748</pre></div>
749<div class="highlight console"><pre><span></span><span class="gp">$ </span>:<span class="w"> </span>default:<span class="w"> </span>update<span class="w"> </span>to<span class="w"> </span>latest<span class="w"> </span>tag<span class="w"> </span>on<span class="w"> </span>default<span class="w"> </span>branch
750<span class="gp">$ </span>pre-commit<span class="w"> </span>autoupdate<span class="w">  </span><span class="c1"># by default: pick tags</span>
751<span class="go">Updating https://github.com/pre-commit/pre-commit-hooks ... updating v2.1.0 -&gt; v2.4.0.</span>
752<span class="go">Updating https://github.com/asottile/pyupgrade ... updating v1.25.0 -&gt; v1.25.2.</span>
753<span class="gp">$ </span>grep<span class="w"> </span>rev:<span class="w"> </span>.pre-commit-config.yaml
754<span class="go">    rev: v2.4.0</span>
755<span class="go">    rev: v1.25.2</span>
756</pre></div>
757<div class="highlight console"><pre><span></span><span class="gp">$ </span>:<span class="w"> </span>update<span class="w"> </span>a<span class="w"> </span>specific<span class="w"> </span>repository<span class="w"> </span>to<span class="w"> </span>the<span class="w"> </span>latest<span class="w"> </span>revision<span class="w"> </span>of<span class="w"> </span>the<span class="w"> </span>default<span class="w"> </span>branch
758<span class="gp">$ </span>pre-commit<span class="w"> </span>autoupdate<span class="w"> </span>
758--bleeding-edge<span class="w"> </span>--repo<span class="w"> </span>https://github.com/pre-commit/pre-commit-hooks
759<span class="go">Updating https://github.com/pre-commit/pre-commit-hooks ... updating v2.1.0 -&gt; 5df1a4bf6f04a1ed3a643167b38d502575e29aef.</span>
760<span class="gp">$ </span>grep<span class="w"> </span>rev:<span class="w"> </span>.pre-commit-config.yaml
761<span class="go">    rev: 5df1a4bf6f04a1ed3a643167b38d502575e29aef</span>
762<span class="go">    rev: v1.25.0</span>
763</pre></div>
764<div class="highlight console"><pre><span></span><span class="gp">$ </span>:<span class="w"> </span>update<span class="w"> </span>to<span class="w"> </span>frozen<span class="w"> </span>versions
765<span class="gp">$ </span>pre-commit<span class="w"> </span>autoupdate<span class="w"> </span>--freeze
766<span class="go">Updating https://github.com/pre-commit/pre-commit-hooks ... updating v2.1.0 -&gt; v2.4.0 (frozen).</span>
767<span class="go">Updating https://github.com/asottile/pyupgrade ... updating v1.25.0 -&gt; v1.25.2 (frozen).</span>
768<span class="gp">$ </span>grep<span class="w"> </span>rev:<span class="w"> </span>.pre-commit-config.yaml
769<span class="go">    rev: 0161422b4e09b47536ea13f49e786eb3616fe0d7  # frozen: v2.4.0</span>
770<span class="go">    rev: 34a269fd7650d264e4de7603157c10d0a9bb8211  # frozen: v1.25.2</span>
771</pre></div>
772<p>pre-commit will preferentially pick tags containing a <code>.</code> if there are ties.</p>
773<h2 id="pre-commit-clean">    pre-commit clean [options] <small><a href="#pre-commit-clean" class="text-decoration-none">¶</a></small></h2> <p>Clean out cached pre-commit files.</p>
774<p>Options: (no additional options)</p>
775<h2 id="pre-commit-gc">    pre-commit gc [options] <small><a href="#pre-commit-gc" class="text-decoration-none">¶</a></small></h2> <p>Clean unused cached repos.</p>
776<p><code>pre-commit</code> keeps a cache of installed hook repositories which grows over
777time.  This command can be run periodically to clean out unused repos from
778the cache directory.</p>
779<p>Options: (no additional options)</p>
780<h2 id="pre-commit-init-templatedir">    pre-commit init-templatedir DIRECTORY [options] <small><a href="#pre-commit-init-templatedir" class="text-decoration-none">¶</a></small></h2> <p>Install hook script in a directory intended for use with
781<code>git config init.templateDir</code>.</p>
782<p>Options:</p>
783<ul>
784<li><code>-t HOOK_TYPE, --hook-type HOOK_TYPE</code>:
785which hook type to install.</li>
786</ul>
787<p>Some example useful invocations:</p>
788<div class="highlight bash"><pre><span></span>git<span class="w"> </span>config<span class="w"> </span>--global<span class="w"> </span>init.templateDir<span class="w"> </span>~/.git-template
789pre-commit<span class="w"> </span>init-templatedir<span class="w"> </span>~/.git-template
790</pre></div>
791<p>For Windows cmd.exe use <code>%HOMEPATH%</code> instead of <code>~</code>:</p>
792<div class="highlight batch"><pre><span></span>pre-commit init-templatedir <span class="nv">%HOMEPATH%</span>\.git-template
793</pre></div>
794<p>For Windows PowerShell use <code>$HOME</code> instead of <code>~</code>:</p>
795<div class="highlight powershell"><pre><span></span><span class="n">pre-commit</span> <span class="n">init-templatedir</span> <span class="nv">$HOME</span><span class="p">\.</span><span class="n">git-template</span>
796</pre></div>
797<p>Now whenever a repository is cloned or created, it will have the hooks set up
798already!</p>
799<h2 id="pre-commit-install">    pre-commit install [options] <small><a href="#pre-commit-install" class="text-decoration-none">¶</a></small></h2> <p>Install the pre-commit script.</p>
800<p>Options:</p>
801<ul>
802<li><code>-f</code>, <code>--overwrite</code>: Replace any existing git hooks with the pre-commit
803script.</li>
804<li><code>--install-hooks</code>: Also install environments for all available hooks now
805(rather than when they are first executed). See <a href="#pre-commit-install-hooks"><code>pre-commit install-hooks</code></a>.</li>
806<li><code>-t HOOK_TYPE, --hook-type HOOK_TYPE</code>:
807Specify which hook type to install.</li>
808<li><code>--allow-missing-config</code>: Hook scripts will permit a missing configuration
809file.</li>
810</ul>
811<p>Some example useful invocations:</p>
812<ul>
813<li><code>pre-commit install</code>: Default invocation. Installs the hook scripts
814alongside any existing git hooks.</li>
815<li><code>pre-commit install --install-hooks --overwrite</code>: Idempotently replaces
816existing git hook scripts with pre-commit, and also installs hook
817environments.</li>
818</ul>
819<p><code>pre-commit install</code> will install hooks from
820<a href="#top_level-default_install_hook_types"><code>default_install_hook_types</code></a> if
821<code>--hook-type</code> is not specified on the command line.</p>
822<h2 id="pre-commit-install-hooks">    pre-commit install-hooks [options] <small><a href="#pre-commit-install-hooks" class="text-decoration-none">¶</a></small></h2> <p>Install all missing environments for the available hooks. Unless this command or
823<code>install --install-hooks</code> is executed, each hook's environment is created the
824first time the hook is called.</p>
825<p>Each hook is initialized in a separate environment appropriate to the language
826the hook is written in. See <a href="#supported-languages">supported languages</a>.</p>
827<p>This command does not install the pre-commit script. To install the script along with
828the hook environments in one command, use <code>pre-commit install --install-hooks</code>.</p>
829<p>Options: (no additional options)</p>
830<h2 id="pre-commit-migrate-config">    pre-commit migrate-config [options] <small><a href="#pre-commit-migrate-config" class="text-decoration-none">¶</a></small></h2> <p>Migrate list configuration to the new map configuration format.</p>
831<p>Options: (no additional options)</p>
832<h2 id="pre-commit-run">    pre-commit run [hook-id] [options] <small><a href="#pre-commit-run" class="text-decoration-none">¶</a></small></h2> <p>Run hooks.</p>
833<p>Options:</p>
834<ul>
835<li><code>[hook-id]</code>: specify a single hook-id to run only that hook.</li>
836<li><code>-a</code>, <code>--all-files</code>: run on all the files in the repo.</li>
837<li><code>--files [FILES [FILES ...]]</code>: specific filenames to run hooks on.</li>
838<li><code>--from-ref FROM_REF</code> + <code>--to-ref TO_REF</code>: run against the files changed
839between <code>
839FROM_REF...TO_REF</code> in git.</li>
840<li><code>--hook-stage STAGE</code>: select a <a href="#confining-hooks-to-run-at-certain-stages"><code>stage</code> to run</a>.</li>
841<li><code>--show-diff-on-failure</code>: when hooks fail, run <code>git diff</code> directly afterward.</li>
842<li><code>-v</code>, <code>--verbose</code>: produce hook output independent of success.  Include hook
843ids in output.</li>
844</ul>
845<p>Some example useful invocations:</p>
846<ul>
847<li><code>pre-commit run</code>: this is what pre-commit runs by default when committing.
848This will run all hooks against currently staged files.</li>
849<li><code>pre-commit run --all-files</code>: run all the hooks against all the files.  This
850is a useful invocation if you are using pre-commit in CI.</li>
851<li><code>pre-commit run flake8</code>: run the <code>flake8</code> hook against all staged files.</li>
852<li><code>git ls-files -- '*.py' | xargs pre-commit run --files</code>: run all hooks
853against all <code>*.py</code> files in the repository.</li>
854<li><code>pre-commit run --from-ref HEAD^^^ --to-ref HEAD</code>: run against the files that
855have changed between <code>HEAD^^^</code> and <code>HEAD</code>.  This form is useful when
856leveraged in a pre-receive hook.</li>
857</ul>
858<h2 id="pre-commit-sample-config">    pre-commit sample-config [options] <small><a href="#pre-commit-sample-config" class="text-decoration-none">¶</a></small></h2> <p>Produce a sample <code>.pre-commit-config.yaml</code>.</p>
859<p>Options: (no additional options)</p>
860<h2 id="pre-commit-try-repo">    pre-commit try-repo REPO [options] <small><a href="#pre-commit-try-repo" class="text-decoration-none">¶</a></small></h2> <p>Try the hooks in a repository, useful for developing new hooks.
861<code>try-repo</code> can also be used for testing out a repository before adding it to
862your configuration.  <code>try-repo</code> prints a configuration it generates based on
863the remote hook repository before running the hooks.</p>
864<p>Options:</p>
865<ul>
866<li><code>REPO</code>: required clonable hooks repository.  Can be a local path on
867disk.</li>
868<li><code>--ref REF</code>: Manually select a ref to run against, otherwise the <code>HEAD</code>
869revision will be used.</li>
870<li><code>pre-commit try-repo</code> also supports all available options for
871<a href="#pre-commit-run"><code>pre-commit run</code></a>.</li>
872</ul>
873<p>Some example useful invocations:</p>
874<ul>
875<li><code>pre-commit try-repo https://github.com/pre-commit/pre-commit-hooks</code>: runs
876all the hooks in the latest revision of <code>pre-commit/pre-commit-hooks</code>.</li>
877<li><code>pre-commit try-repo ../path/to/repo</code>: run all the hooks in a repository on
878disk.</li>
879<li><code>pre-commit try-repo ../pre-commit-hooks flake8</code>: run only the <code>flake8</code> hook
880configured in a local <code>../pre-commit-hooks</code> repository.</li>
881<li>See <a href="#pre-commit-run"><code>pre-commit run</code></a> for more useful <code>run</code> invocations
882which are also supported by <code>pre-commit try-repo</code>.</li>
883</ul>
884<h2 id="pre-commit-uninstall">    pre-commit uninstall [options] <small><a href="#pre-commit-uninstall" class="text-decoration-none">¶</a></small></h2> <p>Uninstall the pre-commit script.</p>
885<p>Options:</p>
886<ul>
887<li><code>-t HOOK_TYPE, --hook-type HOOK_TYPE</code>: which hook type to uninstall.</li>
888</ul>
889<h2 id="pre-commit-validate-config">    pre-commit validate-config [options] [filenames ...] <small><a href="#pre-commit-validate-config" class="text-decoration-none">¶</a></small></h2> <p>Validate .pre-commit-config.yaml files</p>
890<h2 id="pre-commit-validate-manifest">    pre-commit validate-manifest [options] [filenames ...] <small><a href="#pre-commit-validate-manifest" class="text-decoration-none">¶</a></small></h2> <p>Validate .pre-commit-hooks.yaml files</p>
891
892</div>
893<div id="advanced">
894    <div class="page-header"><h1 id="advanced-features">    Advanced features <small><a href="#advanced-features" class="text-decoration-none">¶</a></small></h1> </div>
895    <h2 id="running-in-migration-mode">    Running in migration mode <small><a href="#running-in-migration-mode" class="text-decoration-none">¶</a></small></h2> <p>By default, if you have existing hooks <code>pre-commit install</code> will install in a
896migration mode which runs both your existing hooks and hooks for pre-commit.
897To disable this behavior, pass <code>-f</code> / <code>--overwrite</code> to the <code>install</code> command.
898If you decide not to use pre-commit, <code>pre-commit uninstall</code> will
899restore your hooks to the state prior to installation.</p>
900<h2 id="temporarily-disabling-hooks">    Temporarily disabling hooks <small><a href="#temporarily-disabling-hooks" class="text-decoration-none">¶</a></small></h2> <p>
900Not all hooks are perfect so sometimes you may need to skip execution of one
901or more hooks. pre-commit solves this by querying a <code>SKIP</code> environment
902variable. The <code>SKIP</code> environment variable is a comma separated list of hook
903ids. This allows you to skip a single hook instead of <code>--no-verify</code>ing the
904entire commit.</p>
905<div class="highlight console"><pre><span></span><span class="gp">$ </span><span class="nv">SKIP</span><span class="o">=</span>flake8<span class="w"> </span>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s2">"foo"</span>
906</pre></div>
907<h2 id="confining-hooks-to-run-at-certain-stages">    Confining hooks to run at certain stages <small><a href="#confining-hooks-to-run-at-certain-stages" class="text-decoration-none">¶</a></small></h2> <p>pre-commit supports many different types of <code>git</code> hooks (not just
908<code>pre-commit</code>!).</p>
909<p>Providers of hooks can select which git hooks they run on by setting the
910<a href="#hooks-stages"><code>stages</code></a> property in <code>.pre-commit-hooks.yaml</code> -- this can
911also be overridden by setting <a href="#config-stages"><code>stages</code></a> in
912<code>.pre-commit-config.yaml</code>.  If <code>stages</code> is not set in either of those places
913the default value will be pulled from the top-level
914<a href="#top_level-default_stages"><code>default_stages</code></a> option (which defaults to <em>all</em>
915stages).  By default, tools are enabled for <a href="#supported-git-hooks">every hook type</a>
916that pre-commit supports.</p>
917<p><em>new in 3.2.0</em>: The values of <code>stages</code> match the hook names.  Previously,
918<code>commit</code>, <code>push</code>, and <code>merge-commit</code> matched <code>pre-commit</code>, <code>pre-push</code>, and
919<code>pre-merge-commit</code> respectively.</p>
920<p>The <code>manual</code> stage (via <code>stages: [manual]</code>) is a special stage which will not
921be automatically triggered by any <code>git</code> hook -- this is useful if you want to
922add a tool which is not automatically run, but is run on demand using
923<code>pre-commit run --hook-stage manual [hookid]</code>.</p>
924<p>If you are authoring a tool, it is usually a good idea to provide an appropriate
925<code>stages</code> property.  For example a reasonable setting for a linter or code
926formatter would be <code>stages: [pre-commit, pre-merge-commit, pre-push, manual]</code>.</p>
927<p>To install <code>pre-commit</code> for particular git hooks, pass <code>--hook-type</code> to
928<code>pre-commit install</code>.  This can be specified multiple times such as:</p>
929<div class="highlight console"><pre><span></span><span class="gp">$ </span>pre-commit<span class="w"> </span>install<span class="w"> </span>--hook-type<span class="w"> </span>pre-commit<span class="w"> </span>--hook-type<span class="w"> </span>pre-push
930<span class="go">pre-commit installed at .git/hooks/pre-commit</span>
931<span class="go">pre-commit installed at .git/hooks/pre-push</span>
932</pre></div>
933<p>Additionally, one can specify a default set of git hook types to be installed
934for by setting the top-level <a href="#top_level-default_install_hook_types"><code>default_install_hook_types</code></a>.</p>
935<p>For example:</p>
936<div class="highlight yaml"><pre><span></span><span class="nt">default_install_hook_types</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">pre-commit</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">pre-push</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">commit-msg</span><span class="p p-Indicator">]</span>
937</pre></div>
938<div class="highlight console"><pre><span></span><span class="gp">$ </span>pre-commit<span class="w">  </span>install
939<span class="go">pre-commit installed at .git/hooks/pre-commit</span>
940<span class="go">pre-commit installed at .git/hooks/pre-push</span>
941<span class="go">pre-commit installed at .git/hooks/commit-msg</span>
942</pre></div>
943<p><a name="pre-commit-during-commits"></a>
944<a name="pre-commit-during-merges"></a>
945<a name="pre-commit-during-clean-merges"></a>
946<a name="pre-commit-during-push"></a>
947<a name="pre-commit-for-commit-messages"></a>
948<a name="pre-commit-for-switching-branches"></a>
949<a name="pre-commit-for-rewriting"></a></p>
950<h2 id="supported-git-hooks">    Supported git hooks <small><a href="#supported-git-hooks" class="text-decoration-none">¶</a></small></h2> <ul>
951<li><a href="#commit-msg">commit-msg</a></li>
952<li><a href="#post-checkout">post-checkout</a></li>
953<li><a href="#post-commit">post-commit</a></li>
954<li><a href="#post-merge">post-merge</a></li>
955<li><a href="#post-rewrite">post-rewrite</a></li>
956<li><a href="#pre-commit">pre-commit</a></li>
957<li><a href="#pre-merge-commit">pre-merge-commit</a></li>
958<li><a href="#pre-push">pre-push</a></li>
959<li><a href="#pre-rebase">pre-rebase</a></li>
960<li><a href="#prepare-commit-msg">prepare-commit-msg</a></li>
961</ul>
962<h3 id="commit-msg">    commit-msg <small><a href="#commit-msg" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_commit_msg">git commit-msg docs</a></p>
963<p><code>commit-msg</code> hooks will be passed a single filename -- this file contains the
964current contents of the commit message to be validated.  The commit will be
965aborted if there is a nonzero exit code.</p>
966<h3 id="post-checkout">    post-checkout <small><a href="#post-checkout" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_post_checkout">git post-checkout docs</a></p>
967<p>post-checkout hooks run <em>after</em> a <code>checkout</code> has occurred and can be used to
968set up or manage state in the repository.</p>
969<p><code>post-checkout</code> hooks do not operate on files so they must be set as
970<code>
970always_run: true</code> or they will always be skipped.</p>
971<p>environment variables:</p>
972<ul>
973<li><code>PRE_COMMIT_FROM_REF</code>: the first argument to the <code>post-checkout</code> git hook</li>
974<li><code>PRE_COMMIT_TO_REF</code>:  the second argument to the <code>post-checkout</code> git hook</li>
975<li><code>PRE_COMMIT_CHECKOUT_TYPE</code>: the third argument to the <code>post-checkout</code> git hook</li>
976</ul>
977<h3 id="post-commit">    post-commit <small><a href="#post-commit" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_post_commit">git post-commit docs</a></p>
978<p><code>post-commit</code> runs after the commit has already succeeded so it cannot be used
979to prevent the commit from happening.</p>
980<p><code>post-commit</code> hooks do not operate on files so they must be set as
981<code>always_run: true</code> or they will always be skipped.</p>
982<h3 id="post-merge">    post-merge <small><a href="#post-merge" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_post_merge">git post-merge docs</a></p>
983<p><code>post-merge</code> runs after a successful <code>git merge</code>.</p>
984<p><code>post-merge</code> hooks do not operate on files so they must be set as
985<code>always_run: true</code> or they will always be skipped.</p>
986<p>environment variables:</p>
987<ul>
988<li><code>PRE_COMMIT_IS_SQUASH_MERGE</code>: the first argument to the <code>post-merge</code> git hook.</li>
989</ul>
990<h3 id="post-rewrite">    post-rewrite <small><a href="#post-rewrite" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_post_rewrite">git post-rewrite docs</a></p>
991<p><code>post-rewrite</code> runs after a git command which modifies history such as
992<code>git commit --amend</code> or <code>git rebase</code>.</p>
993<p><code>post-rewrite</code> hooks do not operate on files so they must be set as
994<code>always_run: true</code> or they will always be skipped.</p>
995<p>environment variables:</p>
996<ul>
997<li><code>PRE_COMMIT_REWRITE_COMMAND</code>: the first argument to the <code>post-rewrite</code> git hook.</li>
998</ul>
999<h3 id="pre-commit">    pre-commit <small><a href="#pre-commit" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_pre_commit">git pre-commit docs</a></p>
1000<p><code>pre-commit</code> is triggered before the commit is finalized to allow checks on the
1001code being committed.  Running hooks on unstaged changes can lead to both
1002false-positives and false-negatives during committing.  pre-commit only runs
1003on the staged contents of files by temporarily stashing the unstaged changes
1004while running hooks.</p>
1005<h3 id="pre-merge-commit">    pre-merge-commit <small><a href="#pre-merge-commit" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_pre_merge_commit">git pre-merge-commit docs</a></p>
1006<p><code>pre-merge-commit</code> fires after a merge succeeds but before the merge commit is
1007created.  This hook runs on all staged files from the merge.</p>
1008<p>Note that you need to be using at least git 2.24 for this hook.</p>
1009<h3 id="pre-push">    pre-push <small><a href="#pre-push" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_pre_push">git pre-push docs</a></p>
1010<p><code>pre-push</code> is triggered on <code>git push</code>.</p>
1011<p>environment variables:</p>
1012<ul>
1013<li><code>PRE_COMMIT_FROM_REF</code>: the revision that is being pushed to.</li>
1014<li><code>PRE_COMMIT_TO_REF</code>: the local revision that is being pushed to the remote.</li>
1015<li><code>PRE_COMMIT_REMOTE_NAME</code>: which remote is being pushed to (for example <code>origin</code>)</li>
1016<li><code>PRE_COMMIT_REMOTE_URL</code>: the url of the remote that is being pushed to (for
1017example <code><a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8aede3fecaede3fee2ffe8a4e9e5e7">[email&#160;protected]</a>:pre-commit/pre-commit</code>)</li>
1018<li><code>PRE_COMMIT_REMOTE_BRANCH</code>: the name of the remote branch to which we are
1019pushing (for example <code>refs/heads/target-branch</code>)</li>
1020<li><code>
1020PRE_COMMIT_LOCAL_BRANCH</code>: the name of the local branch that is being pushed
1021to the remote (for example <code>HEAD</code>)</li>
1022</ul>
1023<h3 id="pre-rebase">    pre-rebase <small><a href="#pre-rebase" class="text-decoration-none">¶</a></small></h3> <p><em>new in 3.2.0</em></p>
1024<p><a href="https://git-scm.com/docs/githooks#_pre_rebase">git pre-rebase docs</a></p>
1025<p><code>pre-rebase</code> is triggered before a rebase occurs.  A hook failure can cancel a
1026rebase from occurring.</p>
1027<p><code>pre-rebase</code> hooks do not operate on files so they must be set as
1028<code>always_run: true</code> or they will always be skipped.</p>
1029<p>environment variables:</p>
1030<ul>
1031<li><code>PRE_COMMIT_PRE_REBASE_UPSTREAM</code>: the first argument to the <code>pre-rebase</code> git hook</li>
1032<li><code>PRE_COMMIT_PRE_REBASE_BRANCH</code>: the second argument to the <code>pre-rebase</code> git hook.</li>
1033</ul>
1034<h3 id="prepare-commit-msg">    prepare-commit-msg <small><a href="#prepare-commit-msg" class="text-decoration-none">¶</a></small></h3> <p><a href="https://git-scm.com/docs/githooks#_prepare_commit_msg">git prepare-commit-msg docs</a></p>
1035<p><code>prepare-commit-msg</code> hooks will be passed a single filename -- this file may
1036be empty or it could contain the commit message from <code>-m</code> or from other
1037templates.  <code>prepare-commit-msg</code> hooks can modify the contents of this file to
1038change what will be committed.  A hook may want to check for <code>GIT_EDITOR=:</code> as
1039this indicates that no editor will be launched.  If a hook exits nonzero, the
1040commit will be aborted.</p>
1041<p>environment variables:</p>
1042<ul>
1043<li><code>PRE_COMMIT_COMMIT_MSG_SOURCE</code>: the second argument to the
1044<code>prepare-commit-msg</code> git hook</li>
1045<li><code>PRE_COMMIT_COMMIT_OBJECT_NAME</code>: the third argument to the
1046<code>prepare-commit-msg</code> git hook</li>
1047</ul>
1048<h2 id="passing-arguments-to-hooks">    Passing arguments to hooks <small><a href="#passing-arguments-to-hooks" class="text-decoration-none">¶</a></small></h2> <p>Sometimes hooks require arguments to run correctly. You can pass static
1049arguments by specifying the <a href="#config-args"><code>args</code></a> property in your <code>.pre-commit-config.yaml</code>
1050as follows:</p>
1051<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/PyCQA/flake8</span>
1052<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">4.0.1</span>
1053<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1054<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">flake8</span>
1055<span class="w">        </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">--max-line-length=131</span><span class="p p-Indicator">]</span>
1056</pre></div>
1057<p>This will pass <code>--max-line-length=131</code> to <code>flake8</code>.</p>
1058<h3 id="arguments-pattern-in-hooks">    Arguments pattern in hooks <small><a href="#arguments-pattern-in-hooks" class="text-decoration-none">¶</a></small></h3> <p>If you are writing your own custom hook, your hook should expect to receive
1059the <a href="#config-args"><code>args</code></a> value and then a list of staged files.</p>
1060<p>For example, assuming a <code>.pre-commit-config.yaml</code>:</p>
1061<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/path/to/your/hook/repo</span>
1062<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">badf00ddeadbeef</span>
1063<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1064<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my-hook-script-id</span>
1065<span class="w">        </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">--myarg1=1</span><span class="p p-Indicator">
1065,</span><span class="w"> </span><span class="nv">--myarg1=2</span><span class="p p-Indicator">]</span>
1066</pre></div>
1067<p>When you next run <code>pre-commit</code>, your script will be called:</p>
1068<div class="highlight"><pre><span></span>path/to/script-or-system-exe --myarg1=1 --myarg1=2 dir/file1 dir/file2 file3
1069</pre></div>
1070<p>If the <a href="#config-args"><code>args</code></a> property is empty or not defined, your script will be called:</p>
1071<div class="highlight"><pre><span></span>path/to/script-or-system-exe dir/file1 dir/file2 file3
1072</pre></div>
1073<p>When creating local hooks, there's no reason to put command arguments
1074into <a href="#config-args"><code>args</code></a> as there is nothing which can override them --
1075instead put your arguments directly in the hook <a href="#hooks-entry"><code>entry</code></a>.</p>
1076<p>For example:</p>
1077<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">local</span>
1078<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1079<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">check-requirements</span>
1080<span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">check requirements files</span>
1081<span class="w">        </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">unsupported</span>
1082<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">python -m scripts.check_requirements --compare</span>
1083<span class="w">        </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">^requirements.*\.txt$</span>
1084</pre></div>
1085<h2 id="repository-local-hooks">    Repository local hooks <small><a href="#repository-local-hooks" class="text-decoration-none">¶</a></small></h2> <p>Repository-local hooks are useful when:</p>
1086<ul>
1087<li>The scripts are tightly coupled to the repository and it makes sense to
1088distribute the hook scripts with the repository.</li>
1089<li>Hooks require state that is only present in a built artifact of your
1090repository (such as your app's virtualenv for pylint).</li>
1091<li>The official repository for a linter doesn't have the pre-commit metadata.</li>
1092</ul>
1093<p>You can configure repository-local hooks by specifying the <a href="#repos-repo"><code>repo</code></a> as the
1094sentinel <code>local</code>.</p>
1095<p>local hooks can use any language which supports <a href="#config-additional_dependencies"><code>additional_dependencies</code></a>
1096or <a href="#docker_image"><code>docker_image</code></a> / <a href="#fail"><code>fail</code></a> / <a href="#pygrep"><code>pygrep</code></a> / <a href="#unsupported"><code>unsupported</code></a> / <a href="#unsupported_script"><code>unsupported_script</code></a>.
1097This enables you to install things which previously would require a trivial
1098mirror repository.</p>
1099<p>A <code>local</code> hook must define <a href="#hooks-id"><code>id</code></a>, <a href="#hooks-name"><code>name</code></a>, <a href="#hooks-language"><code>language</code></a>,
1100<a href="#hooks-entry"><code>entry</code></a>, and <a href="#hooks-files"><code>files</code></a> / <a href="#hooks-types"><code>types</code></a>
1101as specified under <a href="#new-hooks">Creating new hooks</a>.</p>
1102<p>Here's an example configuration with a few <code>local</code> hooks:</p>
1103<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">local</span>
1104<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1105<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pylint</span>
1106<span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pylint</span>
1107<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pylint</span>
1108<span class="w">        </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">unsupported</span>
1109<span class="w">        </span><span class="nt">types</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">python</span><span class="p p-Indicator">]</span>
1110<span class="w">        </span><span class="nt">
1110require_serial</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
1111<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">check-x</span>
1112<span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Check X</span>
1113<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">./bin/check-x.sh</span>
1114<span class="w">        </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">unsupported_script</span>
1115<span class="w">        </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">\.x$</span>
1116<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">scss-lint</span>
1117<span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">scss-lint</span>
1118<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">scss-lint</span>
1119<span class="w">        </span><span class="nt">language</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">
1119ruby</span>
1120<span class="w">        </span><span class="nt">language_version</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2.1.5</span>
1121<span class="w">        </span><span class="nt">types</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">scss</span><span class="p p-Indicator">]</span>
1122<span class="w">        </span><span class="nt">additional_dependencies</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="s">'scss_lint:0.52.0'</span><span class="p p-Indicator">]</span>
1123</pre></div>
1124<h2 id="meta-hooks">    meta hooks <small><a href="#meta-hooks" class="text-decoration-none">¶</a></small></h2> <p><code>pre-commit</code> provides several hooks which are useful for checking the
1125pre-commit configuration itself.  These can be enabled using <code>repo: meta</code>.</p>
1126<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">meta</span>
1127<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1128<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
1129</pre></div>
1130<p>The currently available <code>meta</code> hooks:</p>
1131<table class="table table-bordered"><tbody><tr><td><p><a id="meta-check_hooks_apply" href="#meta-check_hooks_apply"><code>check-hooks-apply</code></a></p>
1132</td><td><p>ensures that the configured hooks apply to at least one file in the
1133repository.</p>
1134</td></tr><tr><td><p><a id="meta-check_useless_excludes" href="#meta-check_useless_excludes"><code>check-useless-excludes</code></a></p>
1135</td><td><p>ensures that <code>exclude</code> directives apply to <em>any</em> file in the
1136repository.</p>
1137</td></tr><tr><td><p><a id="meta-identity" href="#meta-identity"><code>identity</code></a></p>
1138</td><td><p>a simple hook which prints all arguments passed to it, useful for
1139debugging.</p>
1140</td></tr></tbody></table><h2 id="codepre-commit-hazmatcode">    <code>pre-commit hazmat</code> <small><a href="#codepre-commit-hazmatcode" class="text-decoration-none">¶</a></small></h2> <p>&quot;hazardous materials&quot;</p>
1141<p>pre-commit provides a few <code>entry</code> prefix &quot;helpers&quot; for unusual situations.</p>
1142<p>in case it's not clear, using these is <em>usually</em> a bad idea.</p>
1143<p><em>note</em>: hazmat helpers do not work on languages which adjust <code>entry</code> (<code>docker</code>
1144/ <code>docker_image</code> / <code>fail</code> / <code>julia</code> / <code>pygrep</code> / <code>r</code> / <code>unsupported_script</code>).</p>
1145<h3 id="codepre-commit-hazmat-cdcode">    <code>pre-commit hazmat cd</code> <small><a href="#codepre-commit-hazmat-cdcode" class="text-decoration-none">¶</a></small></h3> <p><em>new in 4.5.0</em></p>
1146<p>for &quot;monorepo&quot; usage one can use this to target a subdirectory.</p>
1147<p>this entry prefix will cd to the target subdir and adjust filename arguments</p>
1148<p>example usage:</p>
1149<div class="highlight yaml"><pre><span></span><span class="c1"># recommended:</span>
1150<span class="c1"># minimum_pre_commit_version: 4.5.0</span>
1151<span class="nt">repos</span><span class="p">:</span>
1152<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
1153<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
1154<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1155<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example</span>
1156<span class="w">        </span><span class="nt">alias</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example-repo1</span>
1157<span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example (repo1)</span>
1158<span class="w">        </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">^repo1/</span>
1159<span class="w">        </span><span class="c1"># important! ends with `--`</span>
1160<span class="w">        </span><span class="c1"># important! copy `args: [...]` to entry and blank out `args: []`</span>
1161<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pre-commit hazmat cd repo1 example-bin --arg1 --</span>
1162<span class="w">        </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[]</span>
1163
1164<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example</span>
1165<span class="w">        </span><span class="nt">alias</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example-repo2</span>
1166<span class="w">        </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example (repo2)</span>
1167<span class="w">        </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">^repo2/</span>
1168<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pre-commit hazmat cd repo2 example-bin --arg1 --</span>
1169<span class="w">        </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[]</span>
1170
1171<span class="w">    </span><span class="c1"># ... etc.</span>
1172</pre></div>
1173<h3 id="codepre-commit-hazmat-ignore-exit-codecode">    <code>pre-commit hazmat ignore-exit-code</code> <small><a href="#codepre-commit-hazmat-ignore-exit-codecode" class="text-decoration-none">¶</a></small></h3> <p><em>new in 4.5.0</em></p>
1174<p>it's a bad idea to introduce warning noise but this gives you a way to do it.</p>
1175<p>example:</p>
1176<div class="highlight yaml"><pre><span></span><span class="c1"># recommended:</span>
1177<span class="c1"># minimum_pre_commit_version: 4.5.0</span>
1178<span class="nt">repos</span><span class="p">:</span>
1179<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
1180<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
1181<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1182<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example</span>
1183<span class="w">        </span><span class="c1"># important! copy `args: [...]` to entry and blank out `args: []`</span>
1184<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pre-commit hazmat ignore-exit-code example-bin --arg1 --</span>
1185<span class="w">        </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[]</span>
1186<span class="w">        </span><span class="c1"># otherwise the output will always be hidden</span>
1187<span class="w">        </span><span class="nt">verbose</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span>
1188</pre></div>
1189<h3 id="codepre-commit-hazmat-n1code">    <code>pre-commit hazmat n1</code> <small><a href="#codepre-commit-hazmat-n1code" class="text-decoration-none">¶</a></small></h3> <p><em>new in 4.5.0</em></p>
1190<p>some hooks only take one filename argument.  this runs them one at a time
1191(which is super slow!)</p>
1192<p>example:</p>
1193<div class="highlight yaml"><pre><span></span><span class="c1"># recommended:</span>
1194<span class="c1"># minimum_pre_commit_version: 4.5.0</span>
1195<span class="nt">repos</span><span class="p">:</span>
1196<span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
1197<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">...</span>
1198<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1199<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">example</span>
1200<span class="w">        </span><span class="c1"># important! ends with `--`</span>
1201<span class="w">        </span><span class="c1"># important! copy `args: [...]` to entry and blank out `args: []`</span>
1202<span class="w">        </span><span class="nt">entry</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pre-commit hazmat n1 example-bin --arg1 --</span>
1203<span class="w">        </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[]</span>
1204</pre></div>
1205<h2 id="usage-with-git-254-hook-configuration">    usage with git 2.54+ hook configuration <small><a href="#usage-with-git-254-hook-configuration" class="text-decoration-none">¶</a></small></h2> <p><em>new in 4.6.0</em>: pre-commit improved support for <code>git config</code>-based hooks.
1206a later version will change <code>pre-commit install</code> to use this approach.</p>
1207<p><a href="https://github.blog/open-source/git/highlights-from-git-2-54/#h-config-based-hooks">git 2.54</a> introduced a new way to install git hook tools via <code>git config</code>.</p>
1208<p>the basic gist is the following enables a hook in a git repo:</p>
1209<div class="highlight bash"><pre><span></span>git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>
1209hook.&lt;name&gt;.event<span class="w"> </span>pre-push
1210git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>hook.&lt;name&gt;.command<span class="w"> </span><span class="s1">'some command here'</span>
1211</pre></div>
1212<p>an example setup with <code>pre-commit</code> might look like:</p>
1213<div class="highlight bash"><pre><span></span><span class="c1"># note, the "hook" name here is `pre-commit.pre-commit`</span>
1214<span class="c1"># for the `pre-commit` "tool" and the `pre-commit` "event"</span>
1215git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>hook.pre-commit.pre-commit.event<span class="w"> </span>pre-commit
1216git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>hook.pre-commit.pre-commit.command<span class="w"> </span><span class="s1">'pre-commit hook-impl --hook-type pre-commit --'</span>
1217
1218<span class="c1"># please follow that naming scheme for future compatibility with `pre-commit install`</span>
1219
1220<span class="c1"># an example with pre-push:</span>
1221<span class="c1">#</span>
1222<span class="c1"># git config set hook.pre-commit.pre-push.event pre-push</span>
1223<span class="c1"># git config set hook.pre-commit.pre-push.command 'pre-commit hook-impl --hook-type pre-push --'</span>
1224</pre></div>
1225<p><code>pre-commit hook-impl</code> is a &quot;hidden&quot; implementation command with these options:</p>
1226<ul>
1227<li><code>--hook-type ...</code>: the <a href="#supported-git-hooks">hook type</a> to use</li>
1228<li><code>--config ...</code>: (optional) path to <code>.pre-commit-config.yaml</code></li>
1229<li><code>--skip-on-missing-config</code>: silently pass when a config is missing</li>
1230</ul>
1231<p>some interesting applications of this:</p>
1232<h3 id="global-installation-of-pre-commit">    &quot;global&quot; installation of pre-commit <small><a href="#global-installation-of-pre-commit" class="text-decoration-none">¶</a></small></h3> <p>with <code>git config set --global ...</code> this can automatically enable pre-commit
1233for all repositories:</p>
1234<div class="highlight bash"><pre><span></span>git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>--global<span class="w"> </span>hook.pre-commit.pre-commit.event<span class="w"> </span>pre-commit
1235git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>--global<span class="w"> </span>hook.pre-commit.pre-commit.command<span class="w"> </span><span class="s1">'pre-commit hook-impl --hook-type pre-commit --skip-on-missing-config --'</span>
1236</pre></div>
1237<ul>
1238<li>this setup <strong>not recommended</strong> as it can lead to accidentally running hooks
1239when interacting with an untrusted repository.</li>
1240<li><code>--skip-on-missing-config</code> is recommended here as arbitrary git repositories
1241may not have a <code>.pre-commit-config.yaml</code>.</li>
1242</ul>
1243<h3 id="always-running-a-hook-on-all-files">    always running a hook on all files <small><a href="#always-running-a-hook-on-all-files" class="text-decoration-none">¶</a></small></h3> <p>since you can configure pre-commit as many times as you want you <em>could</em> invoke
1244pre-commit to run a particular hook always and on all files</p>
1245<div class="highlight bash"><pre><span></span>git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>hook.pre-commit.pre-commit-always.event<span class="w"> </span>pre-commit
1246git<span class="w"> </span>config<span class="w"> </span><span class="nb">set</span><span class="w"> </span>hook.pre-commit.pre-commit-always.command<span class="w"> </span><span class="s1">'pre-commit run hookid --hook-stage pre-commit --all-files'</span>
1247</pre></div>
1248<p><em>note</em>: this is not recommended as it has the tendancy to be slow and deviates
1249from the normal expectations of pre-commit.</p>
1250<h2 id="automatically-enabling-pre-commit-on-repositories">    automatically enabling pre-commit on repositories <small><a href="#automatically-enabling-pre-commit-on-repositories" class="text-decoration-none">¶</a></small></h2> <p><em>note</em>: if you are on a new-enough version of <code>git</code> you may want to use
1251<a href="#global-installation-of-pre-commit">this approach</a> instead.</p>
1252<hr />
1253<p><code>pre-commit init-templatedir</code> can be used to set up a skeleton for <code>git</code>'s
1254<code>init.templateDir</code> option.  This means that any newly cloned repository will
1255automatically have the hooks set up without the need to run
1256<code>pre-commit install</code>.</p>
1257<p>To configure, first set <code>git</code>'s <code>init.templateDir</code> -- in this example I'm
1258using <code>~/.git-template</code> as my template directory.</p>
1259<div class="highlight console"><pre><span></span><span class="gp">$ </span>git<span class="w"> </span>config<span class="w"> </span>--global<span class="w"> </span>init.templateDir<span class="w"> </span>~/.git-template
1260<span class="gp">$ </span>pre-commit<span class="w"> </span>init-templatedir<span class="w"> </span>~/.git-template
1261<span class="go">pre-commit installed at /home/asottile/.git-template/hooks/pre-commit</span>
1262</pre></div>
1263<p>Now whenever you clone a pre-commit enabled repo, the hooks will already be
1264set up!</p>
1265<div class="highlight pre-commit"><pre><span></span>$ git clone -q <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fb9c928fbb9c928f938e99d5989496">[email&#160;protected]</a>:asottile/pyupgrade
1266$ cd pyupgrade
1267$ git commit --allow-empty -m 'Hello world!'
1268Check docstring is first.............................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
1269Check Yaml...........................................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
1270Debug Statements (Python)............................(no files to check)<span class=" -Color -Color-Black -Color-Black-BGCyan">Skipped</span>
1271...
1272</pre></div>
1273<p><code>init-templatedir</code> uses the <code>--allow-missing-config</code> option from
1274<code>pre-commit install</code> so repos without a config will be skipped:</p>
1275<div class="highlight console"><pre><span></span><span class="gp">$ </span>git<span class="w"> </span>init<span class="w"> </span>sample
1276<span class="go">Initialized empty Git repository in /tmp/sample/.git/</span>
1277<span class="gp">$ </span><span class="nb">cd</span><span class="w"> </span>sample
1278<span class="gp">$ </span>git<span class="w"> </span>commit<span class="w"> </span>--allow-empty<span class="w"> </span>-m<span class="w"> </span><span class="s1">'Initial commit'</span>
1279<span class="go">`.pre-commit-config.yaml` config file not found. Skipping `pre-commit`.</span>
1280<span class="go">[main (root-commit) d1b39c1] Initial commit</span>
1281</pre></div>
1282<p>To still require opt-in, but prompt the user to set up pre-commit use a
1283template hook as follows (for example in <code>~/.git-template/hooks/pre-commit</code>).</p>
1284<div class="highlight bash"><pre><span></span><span class="ch">#!/usr/bin/env bash</span>
1285<span class="k">if</span><span class="w"> </span><span class="o">[</span><span class="w"> </span>-f<span class="w"> </span>.pre-commit-config.yaml<span class="w"> </span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="k">then</span>
1286<span class="w">    </span><span class="nb">echo</span><span class="w"> </span><span class="s1">'pre-commit configuration detected, but `pre-commit install` was never run'</span><span class="w"> </span><span class="m">1</span>&gt;<span class="p">&amp;</span><span class="m">2</span>
1287<span class="w">    </span><span class="nb">exit</span><span class="w"> </span><span class="m">1</span>
1288<span class="k">fi</span>
1289</pre></div>
1290<p>With this, a forgotten <code>pre-commit install</code> produces an error on commit:</p>
1291<div class="highlight console"><pre><span></span><span class="gp">$ </span>git<span class="w"> </span>clone<span class="w"> </span>-q<span class="w"> </span>https://github.com/asottile/pyupgrade
1292<span class="gp">$ </span><span class="nb">cd</span><span class="w"> </span>pyupgrade/
1293<span class="gp">$ </span>git<span class="w"> </span>commit<span class="w"> </span>-m<span class="w"> </span><span class="s1">'foo'</span>
1294<span class="go">pre-commit configuration detected, but `pre-commit install` was never run</span>
1295</pre></div>
1296<h2 id="filtering-files-with-types">    Filtering files with types <small><a href="#filtering-files-with-types" class="text-decoration-none">¶</a></small></h2> <p>Filtering with <code>types</code> provides several advantages over traditional filtering
1297with <code>files</code>.</p>
1298<ul>
1299<li>no error-prone regular expressions</li>
1300<li>files can be matched by their shebang (even when extensionless)</li>
1301<li>symlinks / submodules can be easily ignored</li>
1302</ul>
1303<p><code>types</code> is specified per hook as an array of tags.  The tags are discovered
1304through a set of heuristics by the
1305<a href="https://github.com/pre-commit/identify">identify</a> library.  <code>identify</code> was
1306chosen as it is a small portable pure python library.</p>
1307<p>Some of the common tags you'll find from identify:</p>
1308<ul>
1309<li><code>file</code></li>
1310<li><code>symlink</code></li>
1311<li><code>directory</code> - in the context of pre-commit this will be a submodule</li>
1312<li><code>executable</code> - whether the file has the executable bit set</li>
1313<li><code>text</code> - whether the file looks like a text file</li>
1314<li><code>binary</code> - whether the file looks like a binary file</li>
1315<li><a href="https://github.com/pre-commit/identify/blob/main/identify/extensions.py">tags by extension / naming convention</a></li>
1316<li><a href="https://github.com/pre-commit/identify/blob/main/identify/interpreters.py">tags by shebang (<code>#!</code>)</a></li>
1317</ul>
1318<p>To discover the type of any file on disk, you can use <code>identify</code>'s cli:</p>
1319<div class="highlight console"><pre><span></span><span class="gp">$ </span>identify-cli<span class="w"> </span>setup.py
1320<span class="go">
1320["file", "non-executable", "python", "text"]</span>
1321<span class="gp">$ </span>identify-cli<span class="w"> </span>some-random-file
1322<span class="go">["file", "non-executable", "text"]</span>
1323<span class="gp">$ </span>identify-cli<span class="w"> </span>--filename-only<span class="w"> </span>some-random-file<span class="p">;</span><span class="w"> </span><span class="nb">echo</span><span class="w"> </span><span class="nv">$?</span>
1324<span class="go">1</span>
1325</pre></div>
1326<p>If a file extension you use is not supported, please
1327<a href="https://github.com/pre-commit/identify">submit a pull request</a>!</p>
1328<p><code>types</code>, <code>types_or</code>, and <code>files</code> are evaluated together with <code>AND</code> when
1329filtering.  Tags within <code>types</code> are also evaluated using <code>AND</code>.</p>
1330<p>Tags within <code>types_or</code> are evaluated using <code>OR</code>.</p>
1331<p>For example:</p>
1332<div class="highlight yaml"><pre><span></span><span class="w">    </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">^foo/</span>
1333<span class="w">    </span><span class="nt">types</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">file</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">python</span><span class="p p-Indicator">]</span>
1334</pre></div>
1335<p>will match a file <code>foo/1.py</code> but will not match <code>setup.py</code>.</p>
1336<p>Another example:</p>
1337<div class="highlight yaml"><pre><span></span><span class="w">    </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">^foo/</span>
1338<span class="w">    </span><span class="nt">types_or</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">javascript</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">jsx</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">ts</span><span class="p p-Indicator">,</span><span class="w"> </span><span class="nv">tsx</span><span class="p p-Indicator">]</span>
1339</pre></div>
1340<p>will match any of <code>foo/bar.js</code> / <code>foo/bar.jsx</code> / <code>foo/bar.ts</code> / <code>foo/bar.tsx</code>
1341but not <code>baz.js</code>.</p>
1342<p>If you want to match a file path that isn't included in a <code>type</code> when using an
1343existing hook you'll need to revert back to <code>files</code> only matching by overriding
1344the <code>types</code> setting.  Here's an example of using <code>check-json</code> against non-json
1345files:</p>
1346<div class="highlight yaml"><pre><span></span><span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">check-json</span>
1347<span class="w">        </span><span class="nt">types</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">file</span><span class="p p-Indicator">]</span><span class="w">  </span><span class="c1"># override `types: [json]`</span>
1348<span class="w">        </span><span class="nt">files</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">\.(json|myext)$</span>
1349</pre></div>
1350<p>Files can also be matched by shebang.  With <code>types: python</code>, an <code>exe</code> starting
1351with <code>#!/usr/bin/env python3</code> will also be matched.</p>
1352<p>As with <code>files</code> and <code>exclude</code>, you can also exclude types if necessary using
1353<code>exclude_types</code>.</p>
1354<h2 id="regular-expressions">    Regular expressions <small><a href="#regular-expressions" class="text-decoration-none">¶</a></small></h2> <p>The patterns for <code>files</code> and <code>exclude</code> are python
1355<a href="https://docs.python.org/3/library/re.html#regular-expression-syntax">regular expressions</a>
1356and are matched with <a href="https://docs.python.org/3/library/re.html#re.search"><code>re.search</code></a>.</p>
1357<p>As such, you can use any of the features that python regexes support.</p>
1358<p>If you find that your regular expression is becoming unwieldy due to a long
1359list of excluded / included things, you may find a
1360<a href="https://docs.python.org/3/library/re.html#re.VERBOSE">verbose</a> regular
1361expression useful.  One can enable this with yaml's multiline literals and
1362the <code>(?x)</code> regex flag.</p>
1363<div class="highlight yaml"><pre><span></span><span class="c1"># ...</span>
1364<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">my-hook</span>
1365<span class="w">        </span><span class="nt">exclude</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">|</span>
1366<span class="w">            </span><span class="no">(?x)^(</span>
1367<span class="w">                </span><span class="no">path/to/file1.py|</span>
1368<span class="w">                </span><span class="no">path/to/file2.py|</span>
1369<span class="w">                </span><span class="no">path/to/file3.py</span>
1370<span class="w">            </span><span class="no">)$</span>
1371</pre></div>
1372<h2 id="overriding-language-version">    Overriding language version <small><a href="#overriding-language-version" class="text-decoration-none">¶</a></small></h2> <p>Sometimes you only want to run the hooks on a specific version of the
1373language. For each language, they default to using the system installed
1374language (So for example if I’m running <code>python3.7</code> and a hook specifies
1375<code>python</code>, pre-commit will run the hook using <code>python3.7</code>). Sometimes you
1376don’t want the default system installed version so you can override this on a
1377per-hook basis by setting the <a href="#config-language_version"><code>language_version</code></a>.</p>
1378<div class="highlight yaml"><pre><span></span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">repo</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">https://github.com/pre-commit/mirrors-scss-lint</span>
1379<span class="w">    </span><span class="nt">rev</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v0.54.0</span>
1380<span class="w">    </span><span class="nt">hooks</span><span class="p">:</span>
1381<span class="w">    </span><span class="p p-Indicator">-</span><span class="w">   </span><span class="nt">id</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">scss-lint</span>
1382<span class="w">        </span><span class="nt">language_version</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2.1.5</span>
1383</pre></div>
1384<p>This tells pre-commit to use ruby <code>2.1.5</code> to run the <code>scss-lint</code> hook.</p>
1385<p>Valid values for specific languages are listed below:</p>
1386<ul>
1387<li>python: Whatever system installed python interpreters you have. The value of
1388this argument is passed as the <code>-p</code> to <code>virtualenv</code>.<ul>
1389<li>on windows the
1390<a href="https://www.python.org/dev/peps/pep-0394/">pep394</a> name will be
1391translated into a py launcher call for portability.  So continue to use
1392names like <code>python3</code> (<code>py -3</code>) or <code>python3.6</code> (<code>py -3.6</code>) even on
1393windows.</li>
1394</ul>
1395</li>
1396<li>node: See <a href="https://github.com/ekalinin/nodeenv#advanced">nodeenv</a>.</li>
1397<li>ruby: See <a href="https://github.com/sstephenson/ruby-build/tree/master/share/ruby-build">ruby-build</a>.</li>
1398<li>rust: <code>language_version</code> is passed to <code>rustup</code></li>
1399<li><em>new in 3.0.0</em> golang: use the versions on <a href="https://go.dev/dl/">go.dev/dl</a> such as <code>1.19.5</code></li>
1400</ul>
1401<p>you can set <a href="#top_level-default_language_version"><code>default_language_version</code></a>
1402at the <a href="#pre-commit-configyaml---top-level">top level</a> in your configuration to
1403control the default versions across all hooks of a language.</p>
1404<div class="highlight yaml"><pre><span></span><span class="nt">default_language_version</span><span class="p">:</span>
1405<span class="w">    </span><span class="c1"># force all unspecified python hooks to run python3</span>
1406<span class="w">    </span><span class="nt">python</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">python3</span>
1407<span class="w">    </span><span class="c1"># force all unspecified ruby hooks to run ruby 2.1.5</span>
1408<span class="w">    </span><span class="nt">ruby</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">2.1.5</span>
1409</pre></div>
1410<h2 id="badging-your-repository">    badging your repository <small><a href="#badging-your-repository" class="text-decoration-none">¶</a></small></h2> <p>you can add a badge to your repository to show your contributors / users that
1411you use pre-commit!</p>
1412<p><a href="https://github.com/pre-commit/pre-commit"><img     src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit"    alt="pre-commit"    class="img-fluid img-thumbnail"></a></p>
1413<ul>
1414<li><p>Markdown:</p>
1415<div class="copyable"><div class="highlight md"><pre><span></span>[<span class="nt">![pre-commit</span>](<span class="na">https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit</span>)](https://github.com/pre-commit/pre-commit)
1416</pre></div>
1417</div></li>
1418<li><p>HTML:</p>
1419<div class="copyable"><div class="highlight html"><pre><span></span><span class="p">&lt;</span><span class="nt">a</span> <span class="na">href</span><span class="o">=</span><span class="s">
1419"https://github.com/pre-commit/pre-commit"</span><span class="p">&gt;&lt;</span><span class="nt">img</span> <span class="na">src</span><span class="o">=</span><span class="s">"https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit"</span> <span class="na">alt</span><span class="o">=</span><span class="s">"pre-commit"</span> <span class="na">style</span><span class="o">=</span><span class="s">"max-width:100%;"</span><span class="p">&gt;&lt;/</span><span class="nt">a</span><span class="p">&gt;</span>
1420</pre></div>
1421</div></li>
1422<li><p>reStructuredText:</p>
1423<div class="copyable"><div class="highlight rst"><pre><span></span><span class="p">..</span> <span class="ow">image</span><span class="p">::</span> https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit
1424   <span class="nc">:target:</span> https://github.com/pre-commit/pre-commit
1425   <span class="nc">:alt:</span> pre-commit
1426</pre></div>
1427</div></li>
1428<li><p>AsciiDoc:</p>
1429<div class="copyable"><div class="highlight"><pre><span></span>image:https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit[pre-commit, link=https://github.com/pre-commit/pre-commit]
1430</pre></div>
1431</div></li>
1432</ul>
1433<h2 id="usage-in-continuous-integration">    Usage in continuous integration <small><a href="#usage-in-continuous-integration" class="text-decoration-none">¶</a></small></h2> <p>pre-commit can also be used as a tool for continuous integration.  For
1434instance, adding <code>pre-commit run --all-files</code> as a CI step will ensure
1435everything stays in tip-top shape.  To check only files which have changed,
1436which may be faster, use something like
1437<code>pre-commit run --from-ref origin/HEAD --to-ref HEAD</code></p>
1438<h2 id="managing-ci-caches">    Managing CI Caches <small><a href="#managing-ci-caches" class="text-decoration-none">¶</a></small></h2> <p><code>pre-commit</code> by default places its repository store in <code>~/.cache/pre-commit</code>
1439-- this can be configured in two ways:</p>
1440<ul>
1441<li><code>PRE_COMMIT_HOME</code>: if set, pre-commit will use that location instead.</li>
1442<li><code>XDG_CACHE_HOME</code>: if set, pre-commit will use <code>$XDG_CACHE_HOME/pre-commit</code>
1443following the <a href="https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html">XDG Base Directory Specification</a>.</li>
1444</ul>
1445<h3 id="pre-commitci-example">    pre-commit.ci example <small><a href="#pre-commitci-example" class="text-decoration-none">¶</a></small></h3> <p>no additional configuration is needed to run in <a href="https://pre-commit.ci">pre-commit.ci</a>!</p>
1446<p>pre-commit.ci also has the following benefits:</p>
1447<ul>
1448<li>it's faster than other free CI solutions</li>
1449<li>it will autofix pull requests</li>
1450<li>it will periodically autoupdate your configuration</li>
1451</ul>
1452<p><a href="https://github.com/pre-commit-ci-demo/demo#results"><img     src="https://raw.githubusercontent.com/pre-commit-ci-demo/demo/main/img/2020-12-15_noop.svg"    alt="pre-commit.ci speed comparison"    class="img-fluid img-thumbnail"></a></p>
1453<h3 id="appveyor-example">    appveyor example <small><a href="#appveyor-example" class="text-decoration-none">¶</a></small></h3> <div class="highlight yaml"><pre><span></span><span class="nt">cache</span><span class="p">:</span>
1454<span class="p p-Indicator">-</span><span class="w"> </span><span class="s">'%USERPROFILE%\.cache\pre-commit'</span>
1455</pre></div>
1456<h3 id="azure-pipelines-example">    azure pipelines example <small><a href="#azure-pipelines-example" class="text-decoration-none">¶</a></small></h3> <p>note: azure pipelines uses immutable caches so the python version and
1457<code>.pre-commit-config.yaml</code> hash must be included in the cache key.  for a
1458repository template, see <a href="https://github.com/asottile/azure-pipeline-templates/blob/main/job--pre-commit.yml"><span class="__cf_email__" data-cfemail="7514061a01011c1910351f1a17585805071058161a18181c015b0c1819">[email&#160;protected]</span></a>.</p>
1459<div class="highlight yaml"><pre><span></span><span class="nt">jobs</span><span class="p">:</span>
1460<span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">job</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">precommit</span>
1461
1462<span class="w">  </span><span class="c1"># ...</span>
1463
1464<span class="w">  </span><span class="nt">variables</span><span class="p">:</span>
1465<span class="w">    </span><span class="nt">
1465PRE_COMMIT_HOME</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">$(Pipeline.Workspace)/pre-commit-cache</span>
1466
1467<span class="w">  </span><span class="nt">steps</span><span class="p">:</span>
1468
1469<span class="w">  </span><span class="c1"># ...</span>
1470
1471<span class="w">  </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">script</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">echo "##vso[task.setvariable variable=PY]$(python -VV)"</span>
1472<span class="w">  </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">task</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">CacheBeta@0</span>
1473<span class="w">    </span><span class="nt">inputs</span><span class="p">:</span>
1474<span class="w">      </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pre-commit | .pre-commit-config.yaml | "$(PY)"</span>
1475<span class="w">      </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">$(PRE_COMMIT_HOME)</span>
1476</pre></div>
1477<h3 id="circleci-example">    circleci example <small><a href="#circleci-example" class="text-decoration-none">¶</a></small></h3> <p>like <a href="#azure-pipelines-example">azure pipelines</a>, circleci also uses immutable
1478caches:</p>
1479<div class="highlight yaml"><pre><span></span><span class="w">  </span><span class="nt">steps</span><span class="p">:</span>
1480<span class="w">  </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">run</span><span class="p">:</span>
1481<span class="w">    </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">|</span>
1482<span class="w">      </span><span class="no">cp .pre-commit-config.yaml pre-commit-cache-key.txt</span>
1483<span class="w">      </span><span class="no">python --version --version &gt;&gt; pre-commit-cache-key.txt</span>
1484<span class="w">  </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">restore_cache</span><span class="p">:</span>
1485<span class="w">    </span><span class="nt">keys</span><span class="p">:</span>
1486<span class="w">    </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1-pc-cache-{{ checksum "pre-commit-cache-key.txt" }}</span>
1487
1488<span class="w">  </span><span class="c1"># ...</span>
1489
1490<span class="w">  </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">save_cache</span><span class="p">:</span>
1491<span class="w">    </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">v1-pc-cache-{{ checksum "pre-commit-cache-key.txt" }}</span>
1492<span class="w">    </span><span class="nt">paths</span><span class="p">:</span>
1493<span class="w">      </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/.cache/pre-commit</span>
1494</pre></div>
1495<p>(source: <a href="https://github.com/Unity-Technologies/ml-agents/pull/3094/files#diff-1d37e48f9ceff6d8030570cd36286a61">@chriselion</a>)</p>
1496<h3 id="github-actions-example">    github actions example <small><a href="#github-actions-example" class="text-decoration-none">¶</a></small></h3> <p><strong>see the <a href="https://github.com/pre-commit/action">official pre-commit github action</a></strong></p>
1497<p>like <a href="#azure-pipelines-example">azure pipelines</a>, github actions also uses
1498immutable caches:</p>
1499<div class="highlight yaml"><pre><span></span><span class="w">    </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">set PY</span>
1500<span class="w">      </span><span class="nt">run</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">echo "PY=$(python -VV | sha256sum | cut -d' ' -f1)" &gt;&gt; $GITHUB_ENV</span>
1501<span class="w">    </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">uses</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">actions/cache@v3</span>
1502<span class="w">      </span><span class="nt">with</span><span class="p">:</span>
1503<span class="w">        </span><span class="nt">path</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">~/.cache/pre-commit</span>
1504<span class="w">        </span><span class="nt">key</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">pre-commit|${{ env.PY }}|${{ hashFiles('.pre-commit-config.yaml') }}</span>
1505</pre></div>
1506<h3 id="gitlab-ci-example">    gitlab CI example <small><a href="#gitlab-ci-example" class="text-decoration-none">¶</a></small></h3> <p>See the <a href="https://docs.gitlab.com/ee/ci/caching/#good-caching-practices">Gitlab caching best practices</a> to fine tune the cache scope.</p>
1507<div class="highlight yaml"><pre><span></span><span class="nt">my_job</span><span class="p">:</span>
1508<span class="w">  </span><span class="nt">variables</span><span class="p">:</span>
1509<span class="w">    </span><span class="nt">
1509PRE_COMMIT_HOME</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">${CI_PROJECT_DIR}/.cache/pre-commit</span>
1510<span class="w">  </span><span class="nt">cache</span><span class="p">:</span>
1511<span class="w">    </span><span class="nt">paths</span><span class="p">:</span>
1512<span class="w">      </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">${PRE_COMMIT_HOME}</span>
1513</pre></div>
1514<p>pre-commit's cache requires to be served from a constant location between the different builds. This isn't the default when using k8s runners
1515on GitLab. In case you face the error <code>InvalidManifestError</code>, set <code>builds_dir</code> to something static e.g <code>builds_dir = &quot;/builds&quot;</code> in your <code>[[runner]]</code> config</p>
1516<h3 id="travis-ci-example">    travis-ci example <small><a href="#travis-ci-example" class="text-decoration-none">¶</a></small></h3> <div class="highlight yaml"><pre><span></span><span class="nt">cache</span><span class="p">:</span>
1517<span class="w">  </span><span class="nt">directories</span><span class="p">:</span>
1518<span class="w">  </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">$HOME/.cache/pre-commit</span>
1519</pre></div>
1520<h2 id="usage-with-tox">    Usage with tox <small><a href="#usage-with-tox" class="text-decoration-none">¶</a></small></h2> <p><a href="https://tox.readthedocs.io/">tox</a> is useful for configuring test / CI tools
1521such as pre-commit.  One feature of <code>tox&gt;=2</code> is it will clear environment
1522variables such that tests are more reproducible.  Under some conditions,
1523pre-commit requires a few environment variables and so they must be
1524allowed to be passed through.</p>
1525<p>When cloning repos over ssh (<code>repo: <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f5929c81b5929c819d8097db969a98">[email&#160;protected]</a>:...</code>), <code>git</code> requires the
1526<code>SSH_AUTH_SOCK</code> variable and will otherwise fail:</p>
1527<div class="highlight pre-commit"><pre><span></span>[INFO] Initializing environment for <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="71161805311618051904135f121e1c">[email&#160;protected]</a>:pre-commit/pre-commit-hooks.
1528An unexpected error has occurred: CalledProcessError: command: ('/usr/bin/git', 'fetch', 'origin', '--tags')
1529return code: 128
1530expected return code: 0
1531stdout: (none)
1532stderr:
1533    <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c7a0aeb387a0aeb3afb2a5e9a4a8aa">[email&#160;protected]</a>: Permission denied (publickey).
1534    fatal: Could not read from remote repository.
1535
1536    Please make sure you have the correct access rights
1537    and the repository exists.
1538
1539Check the log at /home/asottile/.cache/pre-commit/pre-commit.log
1540</pre></div>
1541<p>Add the following to your tox testenv:</p>
1542<div class="highlight ini"><pre><span></span><span class="k">[testenv]</span>
1543<span class="na">passenv</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">SSH_AUTH_SOCK</span>
1544</pre></div>
1545<p>Likewise, when cloning repos over http / https
1546(<code>repo: https://github.com:...</code>), you might be working behind a corporate
1547http(s) proxy server, in which case <code>git</code> requires the <code>http_proxy</code>,
1548<code>https_proxy</code> and <code>no_proxy</code> variables to be set, or the clone may fail:</p>
1549<div class="highlight ini"><pre><span></span><span class="k">[testenv]</span>
1550<span class="na">passenv</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">http_proxy https_proxy no_proxy</span>
1551</pre></div>
1552<h2 id="using-the-latest-version-for-a-repository">    Using the latest version for a repository <small><a href="#using-the-latest-version-for-a-repository" class="text-decoration-none">¶</a></small></h2> <p><code>pre-commit</code> configuration aims to give a repeatable and fast experience and
1553therefore intentionally doesn't provide facilities for &quot;unpinned latest
1554version&quot; for hook repositories.</p>
1555<p>Instead, <code>pre-commit</code> provides tools to make it easy to upgrade to the
1556latest versions with <a href="#pre-commit-autoupdate"><code>pre-commit autoupdate</code></a>.  If
1557you need the absolute latest version of a hook (instead of the latest tagged
1558version), pass the <code>--bleeding-edge</code> parameter to <code>autoupdate</code>.</p>
1559<p><code>pre-commit</code> assumes that the value of <a href="#repos-rev"><code>rev</code></a> is an immutable ref (such as a
1560tag or SHA) and will cache based on that.  Using a branch name (or <code>HEAD</code>) for
1561the value of <a href="#repos-rev"><code>rev</code></a> is not supported and will only represent the state of
1562that mutable ref at the time of hook installation (and will <em>NOT</em> update
1563automatically).</p>
1564
1565</div>
1566<div id="contributing">
1567    <div class="page-header">
1567<h1 id="contributing">    Contributing <small><a href="#contributing" class="text-decoration-none">¶</a></small></h1> </div>
1568    <p>We’re looking to grow the project and get more contributors especially to
1569support more languages/versions. We’d also like to get the
1570.pre-commit-hooks.yaml files added to popular linters without maintaining
1571forks / mirrors.</p>
1572<p>Feel free to submit bug reports, pull requests, and feature requests.</p>
1573<h2 id="sponsoring">    Sponsoring <small><a href="#sponsoring" class="text-decoration-none">¶</a></small></h2> <p>If you or your company would like to support the development of pre-commit one
1574can contribute in the following ways:</p>
1575<ul>
1576<li><a href="https://github.com/sponsors/asottile">GitHub Sponsors (asottile)</a></li>
1577<li><a href="https://opencollective.com/pre-commit">Open Collective</a></li>
1578</ul>
1579<h2 id="getting-help">    Getting help <small><a href="#getting-help" class="text-decoration-none">¶</a></small></h2> <p>There are several ways to get help for pre-commit:</p>
1580<ul>
1581<li>Ask a question on <a href="https://stackoverflow.com/questions/tagged/pre-commit.com">stackoverflow tagged <kbd>pre-commit.com</kbd></a></li>
1582<li>Create an issue on <a href="https://github.com/pre-commit/pre-commit/issues/">pre-commit/pre-commit</a></li>
1583<li>Ask in the #pre-commit channel in <a href="https://discord.gg/xDKGPaW">asottile's twitch discord</a></li>
1584</ul>
1585<h2 id="contributors">    Contributors <small><a href="#contributors" class="text-decoration-none">¶</a></small></h2> <ul>
1586<li>website by <a href="https://github.com/mfnkl">Molly Finkle</a></li>
1587<li>created by <a href="https://github.com/asottile">Anthony Sottile</a></li>
1588<li>core developers: <a href="https://github.com/struys">Ken Struys</a>,
1589<a href="https://github.com/chriskuehl">Chris Kuehl</a></li>
1590<li><a href="https://github.com/pre-commit/pre-commit/graphs/contributors">framework contributors</a></li>
1591<li><a href="https://github.com/pre-commit/pre-commit-hooks/graphs/contributors">core hook contributors</a></li>
1592<li>and users like you!</li>
1593</ul>
1594
1595</div>
1596
1597    </div>
1598</div>
1599
1600        </main>
1601
1602        <footer class="navbar navbar-expand navbar-dark bg-primary">
1603            <div class="container-md">&nbsp;</div>
1604        </footer>
vendor: 118 bytes, lines 1604-1606
1604
1605
1606        <script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script>
1606<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
1606
1607        
1607<script>
vendor: 394 bytes, lines 1607-1612
1607
1608            (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
1609            (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
1610            m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
1611            })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
1612            ga('create', '
1612UA-104682927-1
vendor: 56 bytes, lines 1612-1614
1612', 'auto');
1613            ga('send', 'pageview');
1614        
1614</script>
1614
1615        
1615<script src="assets/copyable.js"></script>
1615
1616    
1616<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"b8bfff8fcf6147d5a2b30de197eb4124","r":1,"spa":2}' crossorigin="anonymous"></script>
1616
1617</body>
1618</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.