You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
hook install writes a junk directory and reports false success when core.hooksPath resolves to a non-POSIX (Windows) path #1385
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/...)
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 namedC:\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.
Fixed on v8 in a789564. Confirmed on current code: on WSL/POSIX Path("C:\\…").is_absolute() is False, so a Windows-absolute core.hooksPath (or git rev-parse --git-path hooks output) was joined under the repo root and mkdir'd as a literal backslash-named junk directory, while install() returned success and the real .git/hooks got nothing. Both branches of _hooks_dir now reject drive-letter / embedded-backslash paths with a clear RuntimeError (suggesting git config --local --unset core.hooksPath), which propagates out of install() as a loud failure instead of false success. Legit POSIX custom hooksPath (e.g. Husky's .husky) still installs. Regression tests added (parametrized Windows-path rejection + POSIX-still-works + no-junk-dir assertion).
Activity
Reject Windows-style git hooks paths instead of creating a junk dir (#…
safishamsi commentedon Jun 19, 2026
Fixed on v8 in
a789564. Confirmed on current code: on WSL/POSIXPath("C:\\…").is_absolute()is False, so a Windows-absolutecore.hooksPath(orgit rev-parse --git-path hooksoutput) was joined under the repo root andmkdir'd as a literal backslash-named junk directory, whileinstall()returned success and the real.git/hooksgot nothing. Both branches of_hooks_dirnow reject drive-letter / embedded-backslash paths with a clearRuntimeError(suggestinggit config --local --unset core.hooksPath), which propagates out ofinstall()as a loud failure instead of false success. Legit POSIX custom hooksPath (e.g. Husky's.husky) still installs. Regression tests added (parametrized Windows-path rejection + POSIX-still-works + no-junk-dir assertion).Reject Windows-style git hooks paths instead of creating a junk dir (G…