I am running some git commands through PowerShell but I am having issues capturing the output.
Many of the ways I have looked into have failed to capture any output at all until I tried using Out-File
. Unfortunately, despite how well this has been working for me, I have found that something is going wrong with the git push
command that is preventing me from capturing the output...
My code looks as follows:
git add . | Out-File $logFilePath -Append
git status . | Out-File $logFilePath -Append
git commit -m "Some Relevant update message" | Out-File $logFilePath -Append
git push origin $branchname | Out-File $logFilePath -Append
When I look at the log files, it shows everything but the output of the git push
. So in troubleshooting this, I removed the | Out-File
from the line and noticed that even the output window was not showing the output of the git push
anymore. It was only when I completely removed the Out-File
from all of the git commands that I was able to get the output to display as expected again. Unfortunately, this put me back at square one.
Does anyone know how to best capture the output of git commands using PowerShell, or can point out what I am doing wrong?
As I explained here, or here, Git command output are done on stderr, not stdout.
So in your case, you need to pipe stderr.
See "Redirection of standard and error output appending to the same log-file" for instance.
Note: with Git 2.16 (Q1 2018), you can try and set first
set GIT_REDIRECT_STDERR=2>&1
Then stderr should be redirected to stdout.
In "PowerShell - Capturing STDERR Output for Git Commands", the OP Brandon points out to the --porcelain
option of (for instance) git push:
& git status --porcelain >> $logFilePath
& git push --porcelain >> $logFilePath
It allows to convert the outputs into a machine readable format and pipe them to the output.
If you'd like to write "normal" PowerShell code that returns the output of git, you can override the command with a function that calls the command. This is because in PowerShell, command are resolved in the order:
So you can write a very trivial function to override git (the application).
function git() {
# Call git with splatting
& (Get-Command git -commandType Application) @args 2>&1
}
This type of function is sometimes called a "v1" or "simple" function (because functions with [CmdletBinding()]
or [Parameter()]
were a v2 addition originally called "advanced functions".
These functions do not have standard PowerShell parameters, like -ErrorAction
, but they will call down to git seamlessly and return a list of results.
Then you can do:
$gitOutput = git status
Of course you still have to parse the results.
If you'd like to skip the pain of parsing git output, I wrote a PowerShell module that uses this trick and allows for extensible conversion of any git command into objects.
It's called ugit.
With ugit, for instance, you can say:
# get all untracked files
git status | Select-Object -ExpandProperty Untracked
# get all branches that are not the current branch or named 'main' or 'master'
git branch |
Where-Object -Not IsCurrentBranch |
Where-Object -Name -NotIn main, master
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With