Skip to content

Commit

Permalink
Use bash to open extensionless hooks on windows
Browse files Browse the repository at this point in the history
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
  • Loading branch information
idbrii committed Jan 13, 2022
1 parent fac6037 commit 8548145
Showing 1 changed file with 13 additions and 1 deletion.
14 changes: 13 additions & 1 deletion git/index/fun.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# NOTE: Autodoc hates it if this is a docstring

from io import BytesIO
from pathlib import Path
import os
from stat import (
S_IFDIR,
Expand Down Expand Up @@ -76,6 +77,10 @@ def hook_path(name: str, git_dir: PathLike) -> str:
return osp.join(git_dir, 'hooks', name)


def _has_file_extension(path):
return osp.splitext(path)[1]


def run_commit_hook(name: str, index: 'IndexFile', *args: str) -> None:
"""Run the commit hook of the given name. Silently ignores hooks that do not exist.
:param name: name of hook, like 'pre-commit'
Expand All @@ -89,8 +94,15 @@ def run_commit_hook(name: str, index: 'IndexFile', *args: str) -> None:
env = os.environ.copy()
env['GIT_INDEX_FILE'] = safe_decode(str(index.path))
env['GIT_EDITOR'] = ':'
cmd = [hp]
try:
cmd = subprocess.Popen([hp] + list(args),
if os.name == "nt" and not _has_file_extension(hp):
# Windows only uses extensions to determine how to open files
# (doesn't understand shebangs). Try using bash to run the hook.
relative_hp = Path(hp).relative_to(index.repo.working_dir).as_posix()
cmd = ["bash.exe", relative_hp]

cmd = subprocess.Popen(cmd + list(args),
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
Expand Down

0 comments on commit 8548145

Please sign in to comment.