Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell Capture Git Output

Problem

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.

Question

Does anyone know how to best capture the output of git commands using PowerShell, or can point out what I am doing wrong?

like image 742
Brandon Avatar asked Nov 17 '17 18:11

Brandon


2 Answers

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.

like image 161
VonC Avatar answered Oct 08 '22 13:10

VonC


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:

  • Alias
  • Function
  • Cmdlet
  • ExternalScript
  • Application (what git.exe is)

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
like image 45
Start-Automating Avatar answered Oct 08 '22 14:10

Start-Automating