Detect and compare installed Git version against vendored Git (#1658)

* Replaced the git version comparison mechanism with actual version comparing
* Add notes regarding the git comparison method

Added a simple mechanism to call and compare the user installed git version against the vendored git version, rather than checking if the `git.exe` executable is located in a `/bin` directory.

This fixes false warnings by actually testing if the user installed git is older, or more recent.

Added a small note regarding how the `init.bat` works, and where to put custom `git.exe` binaries as well as where to find the Minified Cmder.
This commit is contained in:
David Refoua 2018-02-22 22:50:08 +03:30 committed by Jack
parent cf311fb1c2
commit 8237b1010c
2 changed files with 131 additions and 9 deletions

View File

@ -147,10 +147,16 @@ Note: These are loaded in this order by '$ENV:CMDER_ROOT\\vendor\\user-profile.p
### SSH Agent ### SSH Agent
To start SSH agent simply call `start-ssh-agent`, which is in the `vendor/git-for-windows/cmd` folder. To start the vendored SSH agent simply call `start-ssh-agent`, which is in the `vendor/git-for-windows/cmd` folder.
If you want to run SSH agent on startup, include the line `@call "%GIT_INSTALL_ROOT%/cmd/start-ssh-agent.cmd"` in `%CMDER_ROOT%/config/user-profile.cmd` (usually just uncomment it). If you want to run SSH agent on startup, include the line `@call "%GIT_INSTALL_ROOT%/cmd/start-ssh-agent.cmd"` in `%CMDER_ROOT%/config/user-profile.cmd` (usually just uncomment it).
### Vendored Git
Cmder is by default shipped with a vendored Git installation. On each instance of launching Cmder, an attempt is made to locate any other user provided Git binaries. Upon finding a `git.exe` binary, Cmder further compares its version against the vendored one _by executing_ it. The vendored `git.exe` binary is _only_ used when it is more recent than the user-installed one.
You may use your favorite version of Git by including its path in the `%PATH%` enviroment variable. Moreover, the **Mini** edition of Cmder (found on the [downloads page](https://github.com/cmderdev/cmder/releases)) excludes any vendored Git binaries.
### Using external Cygwin/Babun, MSys2, or Git for Windows SDK with Cmder. ### Using external Cygwin/Babun, MSys2, or Git for Windows SDK with Cmder.
1. Setup a new task by pressing '<kbd>Win</kbd> +<kbd>Alt</kbd> + <kbd>T</kbd>'. 1. Setup a new task by pressing '<kbd>Win</kbd> +<kbd>Alt</kbd> + <kbd>T</kbd>'.

124
vendor/init.bat vendored
View File

@ -47,26 +47,54 @@ if not defined TERM set TERM=cygwin
:: * if the users points as to a specific git, use that :: * if the users points as to a specific git, use that
:: * test if a git is in path and if yes, use that :: * test if a git is in path and if yes, use that
:: * last, use our vendored git :: * last, use our vendored git
:: also check that we have a recent enough version of git (e.g. test for GIT\cmd\git.exe) :: also check that we have a recent enough version of git by examining the version string
if defined GIT_INSTALL_ROOT ( if defined GIT_INSTALL_ROOT (
if exist "%GIT_INSTALL_ROOT%\cmd\git.exe" (goto :FOUND_GIT) if exist "%GIT_INSTALL_ROOT%\cmd\git.exe" (goto :FOUND_GIT)
) )
:: get the version information for vendored git binary
setlocal enabledelayedexpansion
call :read_version VENDORED "%CMDER_ROOT%\vendor\git-for-windows\cmd"
:: check if git is in path... :: check if git is in path...
setlocal enabledelayedexpansion setlocal enabledelayedexpansion
for /F "delims=" %%F in ('where git.exe 2^>nul') do @( for /F "delims=" %%F in ('where git.exe 2^>nul') do @(
:: get the absolute path to the user provided git binary
pushd %%~dpF pushd %%~dpF
cd ..
set "test_dir=!CD!" set "test_dir=!CD!"
popd popd
if exist "!test_dir!\cmd\git.exe" (
:: get the version information for the user provided git binary
setlocal enabledelayedexpansion
call :read_version USER !test_dir!
if !errorlevel! geq 0 (
:: compare the user git version against the vendored version
setlocal enabledelayedexpansion
call :compare_versions USER VENDORED
:: use the user provided git if its version is greater than, or equal to the vendored git
if !errorlevel! geq 0 (
set "GIT_INSTALL_ROOT=!test_dir!" set "GIT_INSTALL_ROOT=!test_dir!"
set test_dir= set test_dir=
goto :FOUND_GIT goto :FOUND_GIT
) else ( ) else (
echo Found old git version in "!test_dir!", but not using... echo Found old !GIT_VERSION_USER! in "!test_dir!", but not using...
set test_dir= set test_dir=
) )
) else (
:: if the user provided git executable is not found
if !errorlevel! equ -255 (
echo No git at "!git_executable!" found.
set test_dir=
)
)
) )
:: our last hope: our own git... :: our last hope: our own git...
@ -191,3 +219,91 @@ exit /b
:verbose-output :verbose-output
if %verbose-output% gtr 0 echo %* if %verbose-output% gtr 0 echo %*
exit /b exit /b
::
:: specific to git version comparing
::
:read_version
:: clear the variables
set GIT_VERSION_%~1=
:: set the executable path
set "git_executable=%~2\git.exe"
:: check if the executable actually exists
if not exist "%git_executable%" (
:: return a negative error code if the executable doesn't exist
exit /b -255
)
:: get the git version in the provided directory
for /F "delims=" %%F in ('%git_executable% --version 2^>nul') do @(
set "GIT_VERSION_%~1=%%F"
)
:: parse the returned string
call :validate_version "%~1" !GIT_VERSION_%~1!
goto :eof
:parse_version
:: process a `git version x.x.x.xxxx.x` formatted string
for /F "tokens=1-3* delims=.,-" %%A in ("%2") do (
set "%~1_MAJOR=%%A"
set "%~1_MINOR=%%B"
set "%~1_PATCH=%%C"
set "%~1_BUILD=%%D"
)
goto :eof
:validate_version
:: check if we have a valid version string
if /I "%~2 %~3"=="GIT VERSION" (
:: now parse the version information into the corresponding variables
call :parse_version %~1 %~4
:: ... and maybe display it, for debugging purposes.
call :verbose-output Found Git Version for %~1: !%~1_MAJOR!.!%~1_MINOR!.!%~1_PATCH!.!%~1_BUILD!
) else (
:: invalid format returned, use the vendored git instead
echo Invalid git version at "%git_executable%" detected!
call :verbose-output Returned version: %~2 %~3 %~4
rem or directly call the VENDORED_GIT
set test_dir=
exit /b -127
)
goto :eof
:compare_versions
:: checks all major, minor, patch and build variables for the given arguments.
:: whichever binary that has the most recent version will be used based on the return code.
:: call :verbose-output Comparing:
:: call :verbose-output %~1: !%~1_MAJOR!.!%~1_MINOR!.!%~1_PATCH!.!%~1_BUILD!
:: call :verbose-output %~2: !%~2_MAJOR!.!%~2_MINOR!.!%~2_PATCH!.!%~2_BUILD!
if !%~1_MAJOR! GTR !%~2_MAJOR! (exit /b 1)
if !%~1_MAJOR! LSS !%~2_MAJOR! (exit /b -1)
if !%~1_MINOR! GTR !%~2_MINOR! (exit /b 1)
if !%~1_MINOR! LSS !%~2_MINOR! (exit /b -1)
if !%~1_PATCH! GTR !%~2_PATCH! (exit /b 1)
if !%~1_PATCH! LSS !%~2_PATCH! (exit /b -1)
if !%~1_BUILD! GTR !%~2_BUILD! (exit /b 1)
if !%~1_BUILD! LSS !%~2_BUILD! (exit /b -1)
:: looks like we have the same versions.
exit /b 0
goto :eof