Repository navigation
mingit: ship BusyBox as sh.exe in the BusyBox-based MinGit - #746
Open
zcsizmadia wants to merge 1 commit into
Open
zcsizmadia wants to merge 1 commit into
zcsizmadia wants to merge 1 commit into
Conversation
This was referenced Sep 17, 2026
The BusyBox-based MinGit ships `busybox.exe` and, via the Git wrapper, `ash.exe`, but no `sh.exe`. Git resolves the shell for `!` aliases, hooks and shell-driven commands with `git_shell_path()`, which looks up `sh` in the PATH and uses the result as argv[0]. When no `sh.exe` is found, the BusyBox fallback in `compat/mingw.c` returns the path of `busybox.exe` itself, and BusyBox then takes `-c` for an applet name: $ git hello -c: applet not found $ git clone C:\src C:\dst -c: applet not found fatal: Could not read from remote repository. This is what git-for-windows/git#5184, git-for-windows/git#5469 and the first half of git-for-windows/git#6107 report, and it still reproduces with MinGit-2.55.0.5-busybox-64-bit.zip when nothing else on the PATH provides an `sh.exe`. BusyBox picks the applet from its own file name, so shipping a copy of `busybox.exe` as `sh.exe` makes it act as `sh` without any extra indirection, as suggested in git-for-windows/git#5184 (comment). With that copy in place, `!` aliases, clones from local paths and hooks with `#!/bin/sh` and `#!/bin/bash` shebangs all work in a PATH-restricted environment. The copy adds one 844 kB executable to the ~33 MB archive. The Git wrapper could stand in as `sh.exe` instead, as it does for `ash.exe`, at the cost of an extra process launch per shell invocation. This is independent of git-for-windows/git#3301 (`core.shell`): once that lands, MinGit-BusyBox can point `core.shell` at this `sh.exe`. Signed-off-by: Zoltan Csizmadia <[email protected]>
zcsizmadia
force-pushed
the
mingit-busybox-sh
branch
from
September 17, 2026 01:25
3c9e4ec to
1117251
Compare
Member
That's prohibitive. We started out MinGit-busybox with less than 20MB and we need to go reducing MinGit again, not increasing it.
The better plan is to drive #3301 forward and supersede this here PR. Once MinGit-busybox specifies |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The BusyBox-based MinGit ships
busybox.exeand, via the Git wrapper,ash.exe, but nosh.exe. Git resolves the shell for!aliases, hooks and other shell-driven commands withgit_shell_path(), which looks upshin the PATH and uses the result as argv[0]. When nosh.exeexists, the BusyBox fallback incompat/mingw.creturns the path ofbusybox.exeitself, and BusyBox then takes-cfor an applet name:This is what git-for-windows/git#5184, git-for-windows/git#5469 and the first half of git-for-windows/git#6107 report. It still reproduces with
MinGit-2.55.0.5-busybox-64-bit.zipwhen the PATH is restricted toC:\Windows\System32,C:\Windowsand MinGit'scmddirectory. FullGIT_TRACE=1output shows.../mingw64/bin/busybox.exe -c 'echo Hello World' ...being spawned.This PR ships a copy of
busybox.exeasmingw64/bin/sh.exein the BusyBox variant, following the suggestion in git-for-windows/git#5184 (comment). BusyBox picks the applet from its own file name, so the copy acts asshwith no extra indirection.Validation, done by copying
busybox.exetosh.exeinside the extracted 2.55.0.5 zip and re-running with the same restricted PATH:git config alias.hello "!echo Hello World"thengit hello-c: applet not found, exit 127Hello World, exit 0git clone C:\path\src dst-c: applet not found, exit 128pre-commithook with#!/bin/shunamereportsMINGW(BusyBox/Win32)pre-commithook with#!/bin/bashsh.exe -c 'echo $0 && uname'.../mingw64/bin/sh,MINGW(BusyBox/Win32)The
-cspawn now shows as.../mingw64/bin/sh.exe -c 'echo Hello World' ...in the trace.Trade-offs
sh.exethe way it does forash.exe, which would be 42 kB instead, at the cost of one extra process launch per shell invocation. I went with the direct copy because of the ongoing work to reduce process launches in ash: avoid unnecessary Windows process launches busybox-w32#17, but I am happy to switch.core.shell): once that lands, MinGit-BusyBox can pointcore.shellat thissh.exe. It also keeps working if the applet heuristic incompat/mingw.cis dropped, since a plain PATH lookup findssh.exe.release.shend to end here (no Git for Windows SDK on this machine), so the change is limited to the copy plus adieon failure, mirroring the surrounding code. Ash -nsyntax check passes.The second half of git-for-windows/git#6107,
bash: can't create /dev/tty, is a separate issue in the terminal prompt fallback and is not addressed here.