-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Git wrapper
One of the more confusing aspects of Git for Windows is that its main entry points (<Git>\git-bash.exe
, <Git>\cmd\git.exe
, <Git>\bin\bash.exe
, where <Git>
is the location into which Git was installed, typically C:\Program Files\Git
) are not the actual binaries implementing the functionality.
All of these executables are variants of the "Git wrapper". Its only purpose is to set a couple of environment variables and then spawn the actual program. For example, Git/bin/bash.exe
will set MSYSTEM
and PATH
and spawn Git/usr/bin/bash.exe
.
The actual programs, e.g. bash.exe
or git.exe
, live in <Git>\usr\bin
and <Git>\mingw64\bin
(or <Git>\mingw32\bin
in 32-bit setups), and the issue is that either links dynamically to some .dll
files (e.g. msys-2.0.dll
). So if we were to add those directories to the PATH
variable, 3rd-party software that links to the same .dll
files would quite possibly be broken (or Git's own programs). Even worse, some of the other .dll
files present in those folders are in much more widespread use, e.g. OpenSSL. This has been the cause for quite a few tickets in the past, and the <Git>\cmd
directory was added to help this, at first having Batch scripts for git
, git-gui
and gitk
, and later those were turned into Visual Basic scripts, but eventually we just bit the bullet and turned them into real executables because we needed more control than scripts allowed us (e.g. to prevent ugly console windows from "flashing").
-
PATH
First of all, the
PATH
variable is modified, so that Git's ownbin
folders come first. This is needed e.g. to ensure that those Git commands that are still implemented as Unix shell scripts find the expected commands (find.exe
, for example, which is a namesake ofC:\Windows\system32\find.exe
, but the latter has a very different purpose from the POSIXfind
expected by Git). -
HOME
The next-important environment variable which the Git wrapper ensures exists is
HOME
, following Git's expectations that that variable exists and points to the current user's home directory. It is unfortunately not quite trivial to figure out what is the correct value for this (find out about some challenges e.g. in this ticket, demonstrating thatUSERPROFILE
is not always the best answer). -
MSYSTEM
To accommodate Git's expectations where it assumes e.g. a Unix shell to be present on the
PATH
, Git for Windows ships with a subset of MSYS2 (find out about more historical context here). MSYS2 can be run in two flavors, MINGW and MSYS and the flavor Git for Windows needs is MINGW. This is specified via theMSYSTEM
variable. -
PLINK_PROTOCOL
While Plink does not enjoy first-class support in Git for Windows (the much-preferred solution is to use the included OpenSSH client), for historical reasons, Git for Windows offers support for it when an existing Plink configuration is detected. To avoid Plink from thinking that it should use the
telnet
protocol instead of thessh
protocol, we setPLINK_PROTOCOL
(unless it is already defined).
For full information, read the source code of the setup_environment()
function of the Git wrapper.
Especially when running scripts that call Git tens of thousands of times, the start-up cost for the Git wrapper might be noticed, and users might want to side-step it. To address this desire, starting with https://github.com/git-for-windows/git/pull/2506 Git for Windows supports the use case the hard-coded absolute path to <Git>\mingw64\bin\git.exe
is used to launch Git, without the need to add it to the PATH
.
This is the Git for Windows wiki. See how-to-participate.