GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — run_commit_hook picks the WSL launcher stub on Windows: bare bash.exe resolves from System32 before PATH · Issue #2198 · gitpython-developers/GitPython

run_commit_hook picks the WSL launcher stub on Windows: bare bash.exe resolves from System32 before PATH #2198

New issue
Copy link
New issue
Copy link
Closed
#2199
Closed
run_commit_hook picks the WSL launcher stub on Windows: bare bash.exe resolves from System32 before PATH#2198
#2199
Copy link

Description

@piyushmakhija28
piyushmakhija28
opened on Jul 30, 2026
Issue body actions

Summary

On Windows, run_commit_hook spawns extensionless hooks as a bare "bash.exe" and leaves the executable lookup to Windows. CreateProcess resolves a bare name in this order:

application dir  ->  parent cwd  ->  System32  ->  Windows dir  ->  PATH

so C:\Windows\System32\bash.exe — the WSL launcher stub, present on any machine where the "Windows Subsystem for Linux" optional feature has been enabled — is found at step 3, before PATH is ever consulted.

If no WSL distro is installed, that stub prints and exits 1:

Windows Subsystem for Linux has no installed distributions.
You can resolve this by installing a distribution with the instructions below:

Use 'wsl.exe --list --online' to list available distributions
and 'wsl.exe --install <Distro>' to install.

GitPython surfaces this as HookExecutionError, so every repo.index.commit() fails on such a machine and the hook body never runs — regardless of what the hook contains.

Version

  • GitPython 3.1.46 (reproduced), and current main still builds cmd = ["bash.exe", ...]
  • Windows 11, Git for Windows 2.x, WSL optional feature enabled with no distro installed

Reproduction

from pathlib import Path
import git

repo = git.Repo.init("scratch")
hook = Path("scratch/.git/hooks/pre-commit")
hook.write_text("#!/bin/sh\necho HOOK RAN\nexit 0\n", newline="\n")
hook.chmod(0o755)

Path("scratch/f.txt").write_text("x\n")
repo.index.add(["f.txt"])
repo.index.commit("test")   # HookExecutionError on a machine with the WSL stub

git commit from Git Bash on the same repo runs the hook fine, which makes this look like a hook or repo problem rather than a library one.

Why the usual workarounds don't apply

Workaround Why it cannot help
Put C:\Program Files\Git\bin on PATH PATH is consulted only after System32
Give the hook an absolute-path shebang run_commit_hook never reads the shebang
Reorder PATH ahead of System32 Irrelevant — System32 is searched before PATH regardless of PATH contents

The only thing that changes the outcome is naming the interpreter by absolute path.

Note on the current comment in the source

The relative-path calculation carries this comment:

Different drives have no relative path on Windows. Git Bash accepts an absolute path in this form, although a relative path is preferable because it also works with the Windows Subsystem for Linux wrapper.

That reads as though WSL bash is an acceptable target. When WSL is a stub with no distro it is not merely acceptable-but-different, it is guaranteed to fail — and because of the CreateProcess search order it is the one that gets selected by default, ahead of Git's own bash.

Suggested fix

Resolve Git for Windows' bash.exe by absolute path and use it explicitly, rejecting any candidate under %SystemRoot%. Candidate order that works well in practice:

  1. the bin/ directory beside the git.exe already on PATH (shutil.which("git") → ../bin/bash.exe)
  2. GIT_INSTALL_ROOT
  3. standard install locations (C:\Program Files\Git, C:\Program Files (x86)\Git)

Falling back to today's bare "bash.exe" when none is found would keep behavior unchanged for anyone currently relying on WSL bash.

I am working around it downstream by patching the single safer_popen call site in git/index/fun.py to rewrite a bare bash.exe / sh.exe argv[0] to Git's absolute bash. Happy to open a PR against run_commit_hook if the approach above looks acceptable.

Possibly related

  • [Windows] Hooks for submodules that are configured outside the submodule repository lead to error in PurePath.relative_to #1999 (closed, not planned) — a different failure in the same Windows hook path
  • OSError: [WinError 193] %1 is not a valid Win32 application when commiting LFS-enabled repository on Windows #971 / Issue while trying to commit - "repo.index.commit" #1129 — the WinError 193 reports that motivated b719e18, the commit that introduced the bash.exe spawn

Activity

  1. Byron
    added a commit that references this issue on Jul 30, 2026

    Resolve Windows hook Bash through PATH (#2198)

    7131bcc
  2. Byron
    closed this as completedin #2199on Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.