Published on

TIL: a git worktree runs hooks from the main checkout .git/hooks, not its own files

Authors

I changed a hook in a worktree, committed, and the old behavior kept running.

Git stores hooks in the common git directory, which every worktree shares. The tracked copy in your branch (for example .githooks/pre-push) is only a file in the working tree. It does nothing until something installs it into .git/hooks.

You can see where git looks from inside the worktree:

git rev-parse --git-path hooks
# /path/to/main-checkout/.git/hooks

To prove it, I put a hook in the main checkout's .git/hooks/pre-commit that prints a line, then committed inside a separate worktree. The line printed.

So an edit to the tracked hook does not apply until the installed copy is updated. Either:

  • Re-run whatever installs the hooks after you change them.
  • Set core.hooksPath to the tracked folder, so git reads the files you edit.

When a hook seems to ignore your change, look at the installed copy before the tracked one.