fix(git): drop global core.hooksPath; rely on init.templateDir + per-repo install#272
Open
JacobPEvans-personal wants to merge 1 commit into
Open
fix(git): drop global core.hooksPath; rely on init.templateDir + per-repo install#272JacobPEvans-personal wants to merge 1 commit into
JacobPEvans-personal wants to merge 1 commit into
Conversation
…repo install Setting core.hooksPath globally makes pre-commit's installer refuse with "Cowardly refusing to install hooks with core.hooksPath set", breaking every Nix dev shell that calls pre-commit install via shellHook (e.g. cachix/git-hooks.nix installationScript). nix-claude-code reproduces this twice per direnv activation. Drop the core.hooksPath setting. ~/.git-templates/hooks files (pre-commit, pre-push, prepare-commit-msg) are still populated by hooks.nix and now flow into new clones via init.templateDir's native template mechanism — passive, no override. Per-repo Nix dev shells handle pre-commit install into .git/hooks/ for existing repos. Migration for existing repos with a stale local core.hooksPath: git config --local --unset core.hooksPath After rebuild, re-fire direnv in any Nix-dev-shell repo to let installationScript populate the hooks normally. Updates comments in hooks.nix + precommit-tools/default.nix to describe the new template/per-repo split instead of the old global override. Assisted-by: Claude <noreply@anthropic.com>
JacobPEvans-personal
added a commit
to dryvist/nix-claude-code
that referenced
this pull request
May 31, 2026
…lock (#31) Pre-commit's installer refuses with "Cowardly refusing to install hooks with core.hooksPath set" when any scope sets the value. The root cause (global core.hooksPath in nix-home) is being removed in dryvist/nix-home#272, but a defensive guard here surfaces a clear, actionable warning if any future regression — global, local, or per-machine drift — sets the value again. Without the guard the user sees the raw stderr twice per direnv activation with no hint that the fix is `git config --unset core.hooksPath`. The guard runs before installationScript; if hooksPath is empty it is a single grep-and-exit, so no perceptible startup cost. Refs: dryvist/nix-home#272 Assisted-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
core.hooksPathfrom the home-manager git config so it no longer cascades to every repoinit.templateDir = ~/.git-templatesso new clones /git initstill get template hooks (passive — no override of per-repo.git/hooks/)hooks.nix+precommit-tools/default.nixto describe the new template + per-repo install modelWhy
A globally-set
core.hooksPathmakes pre-commit's installer refuse:Reproduces consistently on every direnv activation in repos that use cachix/git-hooks.nix (e.g. nix-claude-code), where
installationScriptrunspre-commit installin the devshellHook. Result: pre-commit framework hooks never install, and the user gets cryptic stderr on everycd.Per-repo Nix dev shells already invoke
pre-commit installcorrectly. Removing the global override hands hook ownership back to them, which is what the cachix/git-hooks.nix design assumes. Layer 1 of the 3-layer defense (perhooks.nixdocs) shifts from "active on ALL repos via core.hooksPath" to "seeded into new clones via templateDir, installed per-repo via dev shell" — same coverage in practice, no conflict with pre-commit framework.Migration
Existing repos with a stale local
core.hooksPath(one was left behind in nix-claude-code) need a one-time:after
darwin-rebuild switch. Thencdre-fires direnv andpre-commit installpopulates.git/hooks/cleanly.Test plan
nix flake checkpasses on the worktreedarwin-rebuild switch,git config --global --get core.hooksPathreturns emptycd ~/git/public/nix-claude-code/maintriggers direnv with no "Cowardly refusing" errorsls -la ~/git/public/nix-claude-code/main/.git/hooks/shows pre-commit framework hooks installedgit inittest repo still receives template hooks viainit.templateDirRefs: cachix/git-hooks.nix design (per-repo installationScript)