⚠ This page is served via a proxy. Original site: https://github.com
This service does not collect credentials or authentication data.
Skip to content

Commit 1a10226

Browse files
Add test for core.hooksPath in bare repositories
Also clean up whitespace and move type import to TYPE_CHECKING block.
1 parent 7977004 commit 1a10226

File tree

2 files changed

+47
-7
lines changed

2 files changed

+47
-7
lines changed

git/index/fun.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
if TYPE_CHECKING:
4949
from git.db import GitCmdObjectDB
5050
from git.objects.tree import TreeCacheTup
51+
from git.repo import Repo
5152

5253
from .base import IndexFile
5354

@@ -61,7 +62,7 @@
6162

6263
def hook_path(name: str, git_dir: PathLike) -> str:
6364
""":return: path to the given named hook in the given git repository directory
64-
65+
6566
Note: This function does not respect the core.hooksPath configuration.
6667
For commit hooks that should respect this config, use run_commit_hook() instead.
6768
"""
@@ -70,25 +71,22 @@ def hook_path(name: str, git_dir: PathLike) -> str:
7071

7172
def _get_hooks_dir(repo: "Repo") -> str:
7273
"""Get the hooks directory, respecting core.hooksPath configuration.
73-
74+
7475
:param repo: The repository to get the hooks directory for.
7576
:return: Path to the hooks directory.
76-
77+
7778
Per git-config documentation, core.hooksPath can be:
7879
- An absolute path: used as-is
7980
- A relative path: relative to the directory where hooks are run from
8081
(typically the working tree root for non-bare repos)
8182
- If not set: defaults to $GIT_DIR/hooks
8283
"""
83-
# Import here to avoid circular imports
84-
from git.repo.base import Repo
85-
8684
try:
8785
hooks_path = repo.config_reader().get_value("core", "hooksPath")
8886
except Exception:
8987
# Config key not found or other error - use default
9088
hooks_path = None
91-
89+
9290
if hooks_path:
9391
hooks_path = str(hooks_path)
9492
if osp.isabs(hooks_path):

test/test_index.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,6 +1135,48 @@ def test_run_commit_hook_respects_relative_core_hookspath(self, rw_repo):
11351135
output = output_file.read_text(encoding="utf-8")
11361136
self.assertEqual(output, "ran from relative hooks path\n")
11371137

1138+
@pytest.mark.xfail(
1139+
type(_win_bash_status) is WinBashStatus.Absent,
1140+
reason="Can't run a hook on Windows without bash.exe.",
1141+
raises=HookExecutionError,
1142+
)
1143+
@pytest.mark.xfail(
1144+
type(_win_bash_status) is WinBashStatus.WslNoDistro,
1145+
reason="Currently uses the bash.exe of WSL, even with no WSL distro installed",
1146+
raises=HookExecutionError,
1147+
)
1148+
@with_rw_repo("HEAD", bare=True)
1149+
def test_run_commit_hook_respects_core_hookspath_bare_repo(self, rw_repo):
1150+
"""Test that run_commit_hook() respects core.hooksPath in bare repositories.
1151+
1152+
For bare repos, relative paths should be resolved relative to git_dir since
1153+
there is no working tree.
1154+
"""
1155+
index = rw_repo.index
1156+
1157+
# Create a custom hooks directory (use absolute path for bare repo)
1158+
# Use a unique name based on the repo to avoid conflicts
1159+
custom_hooks_dir = Path(rw_repo.git_dir).parent / "bare-custom-hooks"
1160+
custom_hooks_dir.mkdir(exist_ok=True)
1161+
1162+
# Create a hook in the custom location
1163+
custom_hook = custom_hooks_dir / "fake-hook"
1164+
custom_hook.write_text(HOOKS_SHEBANG + "echo 'ran from custom hooks path in bare repo' >output.txt")
1165+
custom_hook.chmod(0o744)
1166+
1167+
# Set core.hooksPath in the repo config (absolute path)
1168+
with rw_repo.config_writer() as config:
1169+
config.set_value("core", "hooksPath", str(custom_hooks_dir))
1170+
1171+
# Run the hook - it should use the custom path
1172+
run_commit_hook("fake-hook", index)
1173+
1174+
# Output goes to cwd, which for bare repos during hook execution is git_dir
1175+
output_file = Path(rw_repo.git_dir) / "output.txt"
1176+
self.assertTrue(output_file.exists(), "Hook should have created output.txt")
1177+
output = output_file.read_text(encoding="utf-8")
1178+
self.assertEqual(output, "ran from custom hooks path in bare repo\n")
1179+
11381180
@ddt.data((False,), (True,))
11391181
@with_rw_directory
11401182
def test_hook_uses_shell_not_from_cwd(self, rw_dir, case):

0 commit comments

Comments
 (0)