Skip to content

Commit 8548145

Browse files
committed
Use bash to open extensionless hooks on windows
Fix gitpython-developers#971. If the hook doesn't have a file extension, then Windows won't know how to run it and you'll get "[WinError 193] %1 is not a valid Win32 application". It's very likely that it's a shell script of some kind, so use bash.exe (commonly installed via Windows Subsystem for Linux). We don't want to run all hooks with bash because they could be .bat files. os.name [seems to be the best way to check for Windows][1] and it should certainly ensure we don't do this on other platforms. [1]: https://stackoverflow.com/questions/1325581/how-do-i-check-if-im-running-on-windows-in-python
1 parent fac6037 commit 8548145

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

Diff for: git/index/fun.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# NOTE: Autodoc hates it if this is a docstring
44

55
from io import BytesIO
6+
from pathlib import Path
67
import os
78
from stat import (
89
S_IFDIR,
@@ -76,6 +77,10 @@ def hook_path(name: str, git_dir: PathLike) -> str:
7677
return osp.join(git_dir, 'hooks', name)
7778

7879

80+
def _has_file_extension(path):
81+
return osp.splitext(path)[1]
82+
83+
7984
def run_commit_hook(name: str, index: 'IndexFile', *args: str) -> None:
8085
"""Run the commit hook of the given name. Silently ignores hooks that do not exist.
8186
:param name: name of hook, like 'pre-commit'
@@ -89,8 +94,15 @@ def run_commit_hook(name: str, index: 'IndexFile', *args: str) -> None:
8994
env = os.environ.copy()
9095
env['GIT_INDEX_FILE'] = safe_decode(str(index.path))
9196
env['GIT_EDITOR'] = ':'
97+
cmd = [hp]
9298
try:
93-
cmd = subprocess.Popen([hp] + list(args),
99+
if os.name == "nt" and not _has_file_extension(hp):
100+
# Windows only uses extensions to determine how to open files
101+
# (doesn't understand shebangs). Try using bash to run the hook.
102+
relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix()
103+
cmd = ["bash.exe", relative_hp]
104+
105+
cmd = subprocess.Popen(cmd + list(args),
94106
env=env,
95107
stdout=subprocess.PIPE,
96108
stderr=subprocess.PIPE,

0 commit comments

Comments
 (0)