Windows: a hook outside the working tree is not found from a repository under %TEMP% (Git Bash mounts it as /tmp) · Issue #2287 · gitpython-developers/GitPython · GitHub
This issue was written by Claude Code, an AI agent, on behalf of the account owner.
What happens
On Windows, with a core.hooksPath outside the working tree (for example a global ~/.config/git/hooks holding a pre-commit hook), IndexFile.commit fails for any repository under the user's temporary directory:
git.exc.HookExecutionError: Hook('C:\Users\<user>\.config\git\hooks\pre-commit') failed due to: exit code(127)
cmdline: C:\Users\<user>\.config\git\hooks\pre-commit
stderr: '/usr/bin/bash: ../../../../../.config/git/hooks/pre-commit: No such file or directory
'
The same hook runs fine from a repository elsewhere (e.g. under C:\data). Test suites that create their repositories in tempfile directories hit it on every commit; on this machine that includes GitPython's own hook tests in test/test_index.py.
Reproduce
Windows 11, Git for Windows 2.50.1, Python 3.14; GitPython 3.1.62 and current main (563cb1f):
git config --global core.hooksPath ~/.config/git/hooks # a directory holding an executable pre-commit hook
run_commit_hook passes Bash the hook's path relative to the working tree, os.path.relpath(hp, index.repo.working_dir), computed on the Windows side: from C:\Users\<user>\AppData\Local\Temp\tmpXXXX\repo, five .. reach C:\Users\<user>. But Git for Windows mounts the user's temporary directory as /tmp (none /tmp usertemp binary,posix=0,noacl 0 0 in its /etc/fstab), so Bash starts in /tmp/tmpXXXX/repo, where the same five .. lead to /:
$ cd /tmp/tmpXXXX/repo && ls ../../../../../.config/git/hooks/pre-commitls: cannot access '../../../../../.config/git/hooks/pre-commit': No such file or directory
A relative path is only valid in Bash while it does not cross a mount point. A hook inside the working tree never does; one outside it can. The relative path was introduced in 9bc287a so that a hook outside the working tree could run at all; a working tree under a mount point was not covered.
Possible fix
Keep the relative path for a hook inside the working tree. When the relative path leaves the working tree, pass the absolute path in POSIX form (C:/...), as is already done for a hook on another drive, if the Bash is Git for Windows' own or one found on PATH: both accept it. The bare bash.exe fallback, which may be the WSL launcher, would keep the relative path. A PR with this change follows.
Activity