Search code examples
gitpowershellcmd

Cannot get exit code from git diff for files


Is it possible to use git diff to compare two files outside of the repo? If so, why is the exit code not zero (0) when there is a difference between the files? What am I missing?

In cmd.exe:

 9:43:55.45 2023-08-04  C:\src\t\scripts>TYPE .\t1.txt
this is t1.txt

 9:43:57.92 2023-08-04  C:\src\t\scripts>TYPE .\t2.txt
this is t2.txt

 9:43:57.94 2023-08-04  C:\src\t\scripts>"C:\Program Files\Git\cmd\git.exe" diff --exit-code --no-index  --ignore-all-space  --shortstat  .\t1.txt .\t1.txt

 9:43:58.04 2023-08-04  C:\src\t\scripts>ECHO %ERRORLEVEL%
0

 9:43:58.04 2023-08-04  C:\src\t\scripts>"C:\Program Files\Git\cmd\git.exe" diff --exit-code --no-index  --ignore-all-space  --shortstat  .\t1.txt .\t2.txt
 1 file changed, 1 insertion(+), 1 deletion(-)

 9:43:58.14 2023-08-04  C:\src\t\scripts>ECHO %ERRORLEVEL%
0

In PowerShell 7.3.6:

PS C:\src\t\scripts> Get-Content -Path .\t1.txt
this is t1.txt
PS C:\src\t\scripts> Get-Content -Path  .\t2.txt
this is t2.txt
PS C:\src\t\scripts> & 'C:\Program Files\Git\cmd\git.exe' diff --exit-code --no-index  --ignore-all-space  --shortstat  .\t1.txt .\t1.txt
PS C:\src\t\scripts> $LASTEXITCODE
0
PS C:\src\t\scripts> & 'C:\Program Files\Git\cmd\git.exe' diff --exit-code --no-index  --ignore-all-space  --shortstat  .\t1.txt .\t2.txt
 1 file changed, 1 insertion(+), 1 deletion(-)
PS C:\src\t\scripts> $LASTEXITCODE
0
PS C:\src\t\scripts> & 'C:\Program Files\Git\cmd\git.exe' diff --exit-code --no-index  --ignore-all-space  --shortstat  .\t1.txt .\t1.txt
PS C:\src\t\scripts> $?
True
PS C:\src\t\scripts> & 'C:\Program Files\Git\cmd\git.exe' diff --exit-code --no-index  --ignore-all-space  --shortstat  .\t1.txt .\t2.txt
 1 file changed, 1 insertion(+), 1 deletion(-)
PS C:\src\t\scripts> $?
True

I am using:

PS C:\src\t\scripts> git --version
git version 2.39.2.windows.1

From the git-diff man page at https://git-scm.com/docs/git-diff

--exit-code
Make the program exit with codes similar to diff(1). That is,
it exits with 1 if there were differences and 0 means no differences.

Yes, git can set a non-zero exit code and returning in cmd.exe and pwsh.exe. Testing git setting the exit code to non-zero in cmd.exe.

 9:54:45.54 2023-08-04  C:\src\t\scripts>TYPE testgit.bat
@"C:\Program Files\Git\cmd\git.exe" >NUL
@ECHO %ERRORLEVEL%
 9:54:56.14 2023-08-04  C:\src\t\scripts>CALL testgit.bat
1

 9:54:58.82 2023-08-04  C:\src\t\scripts>testgit.bat
1

Testing git setting the exit code to non-zero in pwsh.exe.

PS C:\src\t\scripts> Get-Content -Path  .\testgit.ps1
& 'C:\Program Files\Git\cmd\git.exe' | Out-Null
$LASTEXITCODE
& 'C:\Program Files\Git\cmd\git.exe' | Out-Null
$?
PS C:\src\t\scripts> .\testgit.ps1
1
False

There is only one (1) git on the system.

PS C:\> Get-Command git -All

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     git.exe                                            2.39.2.1   C:\Program Files\Git\cmd\git.exe

Solution

  • This is a bug that only shows up for me when combining --ignore-all-space and kin with summary stats (--shortstat and kin), as a workaround add --quiet and you'll get the return code (but no other output, if you really need the ignore-all-space shortstat output and the return code you'll need two runs).