Summary
When git rev-parse --git-path hooks returns a path that is not a resolvable POSIX directory — e.g. a Windows-style absolute path such as C:\Users\<user>\<repo>\.git\hooks — graphify hook install does not detect this. It path-joins the unresolvable value onto the current working directory, creating a literal junk directory (backslashes and all) inside the repository working tree, writes the hooks there, and prints a false "installed" success message. The real .git/hooks directory receives nothing, so no hook ever fires.
Reproducible in WSL when operating on a repo whose git config has core.hooksPath set (local scope) to a Windows absolute path — a common state when the same repo is used from both Windows-native git and WSL git.
Environment
- graphify 0.8.41 (installed via
uv tool)
- WSL2 (Linux) operating on a repo checked out on the Windows filesystem (
/mnt/c/...)
git config --local --get core.hooksPath → C:\Users\<user>\<repo>\.git\hooks
- Consequently
git rev-parse --git-path hooks → C:\Users\<user>\<repo>\.git\hooks (unresolvable as a POSIX path from WSL)
Steps to reproduce
- In WSL, in a repo whose local git config has
core.hooksPath set to a Windows-style absolute path (so git rev-parse --git-path hooks returns C:\...\.git\hooks).
- Run
graphify hook install.
Actual behavior
Output (paths genericized):
post-commit: installed at /mnt/c/Users/<user>/<repo>/C:\Users\<user>\<repo>\.git\hooks/post-commit
post-checkout: installed at /mnt/c/Users/<user>/<repo>/C:\Users\<user>\<repo>\.git\hooks/post-checkout
- A directory literally named
C:\Users\<user>\<repo>\.git\hooks (with backslashes in the name) is created inside the working tree, containing post-commit / post-checkout.
- The real
.git/hooks directory is untouched — no hook is installed where git looks.
- The command exits 0 and reports success.
This junk path is also a hazard: it is an untracked file in the working tree that can easily be git add-ed by accident.
Expected behavior
hook install should validate the resolved hooks directory and either:
- correctly resolve / normalize a non-POSIX
core.hooksPath (e.g. translate a C:\... path to its /mnt/c/... equivalent under WSL), or
- fail loudly with a clear error (e.g. "hooks path
<x> is not a writable directory on this platform; check core.hooksPath") and write nothing.
It should never path-join an unresolvable value onto the cwd and write a junk directory into the working tree, nor report success when nothing was installed where git looks.
Workaround
If core.hooksPath is pointing at the default hooks location anyway (just expressed as a Windows absolute path), unsetting it makes git resolve $GIT_DIR/hooks relatively, which works from both WSL and Windows:
git config --local --unset core.hooksPath
# then `graphify hook install` installs into .git/hooks correctly
Additionally: merge driver not configured (possible README/behavior mismatch)
The README states graphify hook install "also sets up a git merge driver" so graph.json is union-merged on concurrent commits. On 0.8.41, hook install installed only the post-commit / post-checkout hooks — no merge.*.driver was configured in git config and no graph.json entry was added to .gitattributes. Either the README or the behavior should be reconciled.
Summary
When
git rev-parse --git-path hooksreturns a path that is not a resolvable POSIX directory — e.g. a Windows-style absolute path such asC:\Users\<user>\<repo>\.git\hooks—graphify hook installdoes not detect this. It path-joins the unresolvable value onto the current working directory, creating a literal junk directory (backslashes and all) inside the repository working tree, writes the hooks there, and prints a false "installed" success message. The real.git/hooksdirectory receives nothing, so no hook ever fires.Reproducible in WSL when operating on a repo whose git config has
core.hooksPathset (local scope) to a Windows absolute path — a common state when the same repo is used from both Windows-native git and WSL git.Environment
uv tool)/mnt/c/...)git config --local --get core.hooksPath→C:\Users\<user>\<repo>\.git\hooksgit rev-parse --git-path hooks→C:\Users\<user>\<repo>\.git\hooks(unresolvable as a POSIX path from WSL)Steps to reproduce
core.hooksPathset to a Windows-style absolute path (sogit rev-parse --git-path hooksreturnsC:\...\.git\hooks).graphify hook install.Actual behavior
Output (paths genericized):
C:\Users\<user>\<repo>\.git\hooks(with backslashes in the name) is created inside the working tree, containingpost-commit/post-checkout..git/hooksdirectory is untouched — no hook is installed where git looks.This junk path is also a hazard: it is an untracked file in the working tree that can easily be
git add-ed by accident.Expected behavior
hook installshould validate the resolved hooks directory and either:core.hooksPath(e.g. translate aC:\...path to its/mnt/c/...equivalent under WSL), or<x>is not a writable directory on this platform; checkcore.hooksPath") and write nothing.It should never path-join an unresolvable value onto the cwd and write a junk directory into the working tree, nor report success when nothing was installed where git looks.
Workaround
If
core.hooksPathis pointing at the default hooks location anyway (just expressed as a Windows absolute path), unsetting it makes git resolve$GIT_DIR/hooksrelatively, which works from both WSL and Windows:Additionally: merge driver not configured (possible README/behavior mismatch)
The README states
graphify hook install"also sets up a git merge driver" sograph.jsonis union-merged on concurrent commits. On 0.8.41,hook installinstalled only thepost-commit/post-checkouthooks — nomerge.*.driverwas configured in git config and nograph.jsonentry was added to.gitattributes. Either the README or the behavior should be reconciled.