Skip to content

Fix commit hooks respecting core.hooksPath - #2159

Merged
Byron merged 2 commits into
gitpython-developers:mainfrom
Siesta0217:fix-core-hooks-path-commit-hooks
Jul 20, 2026
Merged

Fix commit hooks respecting core.hooksPath#2159
Byron merged 2 commits into
gitpython-developers:mainfrom
Siesta0217:fix-core-hooks-path-commit-hooks

Conversation

@Siesta0217

@Siesta0217 Siesta0217 commented May 31, 2026

Copy link
Copy Markdown

Tasks

  • refackiew

Created by Codex on behalf of Byron. Byron will review before this is ready to merge.

Summary

  • Read the effective core.hooksPath setting case-insensitively through GitPython configuration only when it is present and non-empty.
  • Preserve the existing .git/hooks behavior—and avoid a Git subprocess—when core.hooksPath is unset or empty.
  • Resolve configured relative hook directories from the directory where commit hooks run, while supporting absolute and home-relative paths.
  • Keep the Windows Bash fallback working for hooks outside the repository worktree.
  • Cover default lookup, mixed-case configuration, non-bare relative paths, and out-of-worktree Windows command construction.

Fixes #2083

Test Plan

  • 31 index tests passed locally.
  • Ruff lint and format checks passed.
  • mypy passed for git/index/fun.py.
  • Full GitHub Actions matrix will be revalidated after the latest review fix.

@Byron Byron left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot.

The test is good, but the implementation needs adjustments.

Comment thread git/index/fun.py

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates GitPython’s commit-hook execution to resolve hook locations via Git itself, so hooks honor core.hooksPath, and adds a regression test to confirm a hook runs from a custom hooks directory.

Changes:

  • Add _commit_hook_path() that resolves hooks/<name> via git rev-parse --git-path, intended to respect core.hooksPath.
  • Switch run_commit_hook() to use _commit_hook_path() instead of hardcoding .git/hooks/<name>.
  • Add a regression test verifying a pre-commit hook runs from a configured custom hooks path.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
git/index/fun.py Adds Git-based hook path resolution and uses it in run_commit_hook().
test/test_index.py Adds a regression test for core.hooksPath hook execution.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread git/index/fun.py Outdated
Comment thread test/test_index.py
Use git rev-parse --git-path when resolving commit hook paths so GitPython follows Git's core.hooksPath configuration.\n\nAdd regression coverage for a pre-commit hook stored in a custom hooks path.\n\nFixes gitpython-developers#2083
Copilot AI review requested due to automatic review settings July 20, 2026 08:18
@Byron
Byron force-pushed the fix-core-hooks-path-commit-hooks branch from 9b3198c to 406b98e Compare July 20, 2026 08:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

git/index/fun.py:99

  • On Windows, run_commit_hook assumes the hook path is under index.repo.working_dir when it builds relative_hp for bash.exe. With core.hooksPath, git rev-parse --git-path hooks/<name> can legitimately return an absolute path outside the working directory (or a relative path that escapes it), which makes Path(hp).relative_to(...) raise ValueError and turns a runnable hook into a HookExecutionError. Consider using os.path.relpath with a fallback to an absolute POSIX path instead of Path.relative_to so hooks configured outside the worktree don't crash.
    hp = _commit_hook_path(name, index)
    if not os.access(hp, os.X_OK):
        return

    env = os.environ.copy()
Copilot AI review requested due to automatic review settings July 20, 2026 08:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread git/index/fun.py
Comment thread git/index/fun.py Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 08:40
@Byron
Byron force-pushed the fix-core-hooks-path-commit-hooks branch from 0702dea to f7aa470 Compare July 20, 2026 08:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Copilot AI review requested due to automatic review settings July 20, 2026 08:49

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread git/index/fun.py Outdated
Comment thread test/test_index.py Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 09:00
@Byron
Byron force-pushed the fix-core-hooks-path-commit-hooks branch from 11a0c30 to fafbdc8 Compare July 20, 2026 09:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread git/index/fun.py Outdated
Copilot AI review requested due to automatic review settings July 20, 2026 09:10

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment thread git/index/fun.py
- Review feedback: resolve core.hooksPath only when configured, avoid an
unconditional git rev-parse dependency, and cover relative paths in a non-bare
repository.
- Read the effective Git configuration directly so unconfigured repositories
retain the legacy .git/hooks lookup and configured relative paths resolve from
the directory where hooks execute. Exercise both guarantees in the hook tests.
- Review feedback: core.hooksPath can point outside index.repo.working_dir,
where Path.relative_to() raises on Windows and prevents a valid hook from
running.
- Build the Bash argument with os.path.relpath so hooks in parent or other
absolute locations remain executable. Fall back to the absolute POSIX-form
path when Windows cannot form a relative path across drives, and add a focused
command-construction regression test.
@Byron
Byron force-pushed the fix-core-hooks-path-commit-hooks branch from 5252136 to 9bc287a Compare July 20, 2026 11:01
Copilot AI review requested due to automatic review settings July 20, 2026 11:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

git/index/fun.py:71

  • _commit_hook_path() uses config.get("core", "hooksPath"), but GitConfigParser is explicitly case-sensitive for section and option names. This means valid Git configs like [Core] hooksPath=... or core.hookspath=... will be ignored and hooks will incorrectly fall back to .git/hooks, so the fix won’t work in many real-world configurations.
def _commit_hook_path(name: str, index: "IndexFile") -> str:
    """:return: path to the named commit hook, respecting Git's core.hooksPath."""
    with index.repo.config_reader() as config:
        hooks_dir = config.get("core", "hooksPath", fallback="")

@Byron
Byron merged commit 354eb2f into gitpython-developers:main Jul 20, 2026
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

5 participants