pre-commit: Setting a global hooks path causes "Cowardly refusing to install" everywhere

I recently setup a global spell checking commit hook that lives in

git config --global core.hooksPath ~/dotfiles/gitHooks

Just noticed that due to this, attempting pre-commit install now fails with

[ERROR] Cowardly refusing to install hooks with `core.hooksPath` set.

in every repo.

Is there actually a reason to fail in the presence of global hooks? Local hooks are still executed unless they’re being shadowed by a global hook of the same name, i.e. a global commit-msg hook would prevent a local commit-msg hook from running. In that case, it’s the user’s responsibility to make sure the global hook calls the local one if so desired.

If there is indeed no reason not to let global and local hooks coincide, fixing this might be as easy as modifying

def has_core_hookpaths_set():
-    _, out, _ = cmd_output_b('git', 'config', 'core.hooksPath', retcode=None)
+    _, out, _ = cmd_output_b('git', 'config', '--local', 'core.hooksPath', retcode=None)
    return bool(out.strip())

Happy to submit a PR for that.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 24 (13 by maintainers)

Commits related to this issue

Most upvoted comments

I played around with it for awhile this afternoon, and it appears that hooksPath, even locally in the repo with .git/config that it wasn’t triggering. Not quite sure why. Probably best to have the error as per patch. What ended up working was an alias pre-commit && git commit

🤷‍♂ ah well, I can possibly revert that later if someone mentions it – for now it’s been released as part of 2.0.0

The problem with templates AFAIU them is that changes made to the template are not reflected in previously created repos, correct? Or could I place a symlink in the template directory and git would copy that symlink into each repo which would all point to a master file that’s always up to date?

This actually also doesn’t help me because it doesn’t retrofit the hook into existing repos.

In any case, I just did a little more testing and it turns out setting a global hooks directory only shadows local hooks if no local hooks path has been set (i.e. if it’s still the default .git/hooks).

If a local hooks directory is set (it can even be set to the default location), local hooks are in fact called (which is why it didn’t notice the behavior you showed above).

What was the reason to not just install the hooks in the user specified local hooks directory if one was specified and have pre-commit itself set it to the default .git/hooks otherwise? Seems to me like that would enable joint use of local and global hooks.

I thought I read that about two weeks ago but apparently I misread or the source was mistaken. Can’t remember/find the source now.

you may find git’s init.templateDir more amenable

The problem with templates AFAIU them is that changes made to the template are not reflected in previously created repos, correct? Or could I place a symlink in the template directory and git would copy that symlink into each repo which would all point to a master file that’s always up to date?