1
0
mirror of https://github.com/j178/prek.git synced 2026-04-25 02:11:36 +02:00

Honor repo and worktree core.hooksPath (#1892)

## Summary

This takes a smaller approach than #1673.

Instead of mutating Git config during install, it lets `prek` ask Git
for the effective hooks directory and:

- honors repo-local (`git config --local`) `core.hooksPath`
- honors worktree-local (`git config --worktree`) `core.hooksPath`
- continues to refuse global/system `core.hooksPath` by default
- aligns `prek uninstall` with the same behavior
- updates the CLI reference and FAQ to document the behavior

This keeps the existing safety boundary for externally configured hook
locations while making linked worktrees and repo-owned hook directories
work without extra wrapper logic.

## Testing

- `cargo test -p prek --test install`
- `PREK_GENERATE=1 cargo test --bin prek
cli::_gen::generate_cli_reference -- --exact`

## Context

Closes #1672
Closes #1673

---------

Co-authored-by: Jo <10510431+j178@users.noreply.github.com>
This commit is contained in:
Sadjow Leão
2026-04-13 06:11:44 -03:00
committed by GitHub
parent 08c1f706ce
commit dc98c4792d
8 changed files with 668 additions and 34 deletions
+7 -3
View File
@@ -12,7 +12,7 @@ prek [OPTIONS] [HOOK|PROJECT]... [COMMAND]
<h3 class="cli-reference">Commands</h3>
<dl class="cli-reference"><dt><a href="#prek-install"><code>prek install</code></a></dt><dd><p>Install prek Git shims under the <code>.git/hooks/</code> directory</p></dd>
<dl class="cli-reference"><dt><a href="#prek-install"><code>prek install</code></a></dt><dd><p>Install prek Git shims into Git's effective hooks directory</p></dd>
<dt><a href="#prek-prepare-hooks"><code>prek prepare-hooks</code></a></dt><dd><p>Prepare environments for all hooks used in the config file</p></dd>
<dt><a href="#prek-run"><code>prek run</code></a></dt><dd><p>Run hooks</p></dd>
<dt><a href="#prek-list"><code>prek list</code></a></dt><dd><p>List hooks configured in the current workspace</p></dd>
@@ -29,7 +29,9 @@ prek [OPTIONS] [HOOK|PROJECT]... [COMMAND]
## prek install
Install prek Git shims under the `.git/hooks/` directory.
Install prek Git shims into Git's effective hooks directory.
By default this is `.git/hooks/`, but repo-local or worktree-local `core.hooksPath` is honored when set.
The Git shims installed by this command are determined by `--hook-type` or `default_install_hook_types` in the config file, falling back to `pre-commit` when neither is set.
@@ -71,7 +73,7 @@ prek install [OPTIONS] [HOOK|PROJECT]...
<li><code>never</code>: Disables colored output</li>
</ul></dd><dt id="prek-install--config"><a href="#prek-install--config"><code>--config</code></a>, <code>-c</code> <i>config</i></dt><dd><p>Path to alternate config file</p>
</dd><dt id="prek-install--git-dir"><a href="#prek-install--git-dir"><code>--git-dir</code></a> <i>git-dir</i></dt><dd><p>Install Git shims into the <code>hooks</code> subdirectory of the given git directory (<code>&lt;GIT_DIR&gt;/hooks/</code>).</p>
<p>When this flag is used, <code>prek install</code> bypasses the safety check that normally refuses to install shims while <code>core.hooksPath</code> is set. Git itself will still ignore <code>.git/hooks</code> while <code>core.hooksPath</code> is configured, so ensure your Git configuration points to the directory where the shim is installed if you want it to be executed.</p>
<p>When this flag is used, <code>prek install</code> bypasses the safety check that normally refuses to install shims while <code>core.hooksPath</code> is configured outside the repo. It only writes shims to <code>&lt;GIT_DIR&gt;/hooks</code>; Git will keep using <code>core.hooksPath</code> until that config changes.</p>
</dd><dt id="prek-install--help"><a href="#prek-install--help"><code>--help</code></a>, <code>-h</code></dt><dd><p>Display the concise help for this command</p>
</dd><dt id="prek-install--hook-type"><a href="#prek-install--hook-type"><code>--hook-type</code></a>, <code>-t</code> <i>hook-type</i></dt><dd><p>Which Git shim(s) to install.</p>
<p>Specifies which Git hook type(s) you want to install shims for. Can be specified multiple times to install shims for multiple hook types.</p>
@@ -398,6 +400,8 @@ prek uninstall [OPTIONS]
<li><code>always</code>: Enables colored output regardless of the detected environment</li>
<li><code>never</code>: Disables colored output</li>
</ul></dd><dt id="prek-uninstall--config"><a href="#prek-uninstall--config"><code>--config</code></a>, <code>-c</code> <i>config</i></dt><dd><p>Path to alternate config file</p>
</dd><dt id="prek-uninstall--git-dir"><a href="#prek-uninstall--git-dir"><code>--git-dir</code></a> <i>git-dir</i></dt><dd><p>Uninstall Git shims from the <code>hooks</code> subdirectory of the given git directory (<code>&lt;GIT_DIR&gt;/hooks/</code>).</p>
<p>When this flag is used, <code>prek uninstall</code> bypasses the safety check that normally refuses to modify shims while <code>core.hooksPath</code> is configured outside the repo. It only removes shims from <code>&lt;GIT_DIR&gt;/hooks</code>; Git may still use the configured <code>core.hooksPath</code> until that config changes.</p>
</dd><dt id="prek-uninstall--help"><a href="#prek-uninstall--help"><code>--help</code></a>, <code>-h</code></dt><dd><p>Display the concise help for this command</p>
</dd><dt id="prek-uninstall--hook-type"><a href="#prek-uninstall--hook-type"><code>--hook-type</code></a>, <code>-t</code> <i>hook-type</i></dt><dd><p>Which Git shim(s) to uninstall.</p>
<p>Specifies which Git hook type(s) you want to uninstall shims for. Can be specified multiple times to uninstall shims for multiple hook types.</p>
+7 -1
View File
@@ -18,13 +18,19 @@ In short, it installs the Git shims **and** prepares the environments for the ho
It's a little confusing because it refers to two different kinds of hooks:
1. **Git shims** – Scripts placed inside `.git/hooks/`, such as `.git/hooks/pre-commit`, that Git executes during lifecycle events. Both prek and ppc drop a small shim here so Git automatically runs them on `git commit`.
1. **Git shims** – Scripts placed in Git's effective hooks directory, usually `.git/hooks/` unless `core.hooksPath` points elsewhere. Both prek and ppc drop a small shim here so Git automatically runs them on `git commit`.
2. **prek-managed hooks** – The tools listed in `.pre-commit-config.yaml`. When prek runs, it executes these hooks and prepares whatever runtime they need (for example, creating a Python virtual environment and installing the hook's dependencies before execution).
Running `prek install` installs the first type: it writes the Git shim so that Git knows to call prek. Which Git shims get installed is determined by `--hook-type` or `default_install_hook_types` in the config file, and defaults to `pre-commit` if neither is set. This is not affected by a hook's `stages` field in the config: `stages` controls when a configured hook may run, not which Git shims `prek install` writes.
Adding `--prepare-hooks` tells prek to do that **and** proactively create the environments and caches required by the hooks that prek manages. That way, the next time Git invokes prek through the shim, the managed hooks are ready to run without additional setup. The older `--install-hooks` spelling remains as an alias.
## How does `prek install` interact with `core.hooksPath` and worktrees?
If `core.hooksPath` is set in repo-local (`git config --local`) or worktree-local (`git config --worktree`) config, `prek install` and `prek uninstall` will honor it and operate on Git's effective hooks directory.
If `core.hooksPath` is only configured globally or system-wide, prek refuses to install or uninstall by default. That setting may be shared across repositories, so prek avoids mutating a hook location it does not own. In that case, remove or change the global/system `core.hooksPath`.
## How do I use hooks from private repositories?
prek supports cloning hooks from private repositories that require authentication.