fix(hooks): expand ~ in core.hooksPath before resolving install target (#554)

When a user configures core.hooksPath = ~/gitconfig/hooks in .gitconfig,
_hooks_dir() was constructing Path("~/gitconfig/hooks") without calling
expanduser(), so hooks were installed into <repo>/~/gitconfig/hooks instead
of the intended absolute path.

Add Path.expanduser() call immediately after reading the raw string from
git config, before the is_absolute() / root-relative fallback logic.

Fixes #547
This commit is contained in:
Koushik-Salammagari
2026-05-02 06:14:46 -07:00
committed by GitHub
parent 441e3b6574
commit e1947826fc
+27
View File
@@ -123,3 +123,30 @@ def test_hook_skips_head_on_exe():
"""Hook script must skip shebang extraction for .exe binaries (Windows)."""
from graphify.hooks import _PYTHON_DETECT
assert "*.exe) _SHEBANG=" in _PYTHON_DETECT or '*.exe)' in _PYTHON_DETECT
def test_hooks_dir_expands_tilde(tmp_path, monkeypatch):
"""_hooks_dir must call expanduser() so ~/... paths in core.hooksPath resolve correctly."""
from graphify.hooks import _hooks_dir
import types
repo = _make_git_repo(tmp_path)
custom_hooks = tmp_path / "custom_hooks"
custom_hooks.mkdir()
# expanduser() reads $HOME, so override it to make ~/custom_hooks predictable
monkeypatch.setenv("HOME", str(tmp_path))
real_run = subprocess.run
def fake_run(cmd, **kwargs):
if isinstance(cmd, list) and "config" in cmd and "core.hooksPath" in cmd:
return types.SimpleNamespace(returncode=0, stdout="~/custom_hooks")
return real_run(cmd, **kwargs)
monkeypatch.setattr(subprocess, "run", fake_run)
resolved = _hooks_dir(repo)
assert resolved == custom_hooks, (
f"expected {custom_hooks}, got {resolved} — tilde was not expanded"
)