I have a simple PowerShell script to keep a folder up-to-date with its git repository.
Param(
[Parameter(Mandatory = $true)][string]$branch,
[string]
Git writes the more verbose data to the Error stream to allow parsers to parse the most important bits. These parsers can then ignore the more verbose output that's meant for the human user. That data is sent through the stderr stream. Powershell converts data on stderr to an error record by default, throwing the error you see.
The following github issue has a whole bunch of possible solutions.
The one that seems to be the simplest is to add --porcelain or --quiet
, which will not write verbose data to stderr or no data at all.
git checkout branch --porcelain
git checkout branch --quiet
Another option is to configure the standard redirect mode for git through the environment, at least this way you don't need to scatter the redirect throughout the whole code:
$env:GIT_REDIRECT_STDERR = '2>&1'
More options are found in this StackOverflow answer, forcing all redirected messages to their string representation works nicely too:
git checkout branch 2>&1 | %{ "$_" }
An alternate syntax for that is:
"$(git checkout branch ? 2>&1 )"
Another workaround is to invoke git through cmd
:
& cmd /c 'git checkout branch 2>&1'
And in this answer you'll find a wrapper function to call git in a clean manner.
function Invoke-Git {
<#
.Synopsis
Wrapper function that deals with Powershell's peculiar error output when Git uses the error stream.
.Example
Invoke-Git ThrowError
$LASTEXITCODE
#>
[CmdletBinding()]
param(
[parameter(ValueFromRemainingArguments=$true)]
[string[]]$Arguments
)
& {
[CmdletBinding()]
param(
[parameter(ValueFromRemainingArguments=$true)]
[string[]]$InnerArgs
)
C:\Full\Path\To\git.exe $InnerArgs
} -ErrorAction SilentlyContinue -ErrorVariable fail @Arguments
if ($fail) {
$fail.Exception
}
}
# Could shorten the function name. I instead alias it, for terseness.
Set-Alias -Name git -Value Invoke-Git
# Also alias the name with the extension, as it is called by some applications this way.
Set-Alias -Name git.exe -Value Invoke-Git
I have encountered this behavior in the past with git commands and PowerShell, I don't know exactly why PS print the success response like an error but I solved it in this way:
$output = git pull 2>&1
Write-Host $output