Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PowerShell Transcript is not capturing git output

Tags:

git

powershell

I'm writing a script that will perform some git actions and I want to use Start-Transcript to monitor it. The transcript is however missing most of the git output.

I've tried to pipe the git output to both Out-Host and Out-Default but neither work.

Here's my code...

$DateTime = Get-Date -Format "yyyyMMdd_HHmmss"
$TranscriptName = "PSTranscript_$DateTime"

Start-Transcript -Path ".\$TranscriptName.txt"

git --bare clone <GIT_REPO_URL> repo | Out-Default

Stop-Transcript

Here's my console output...

Transcript started, output file is .\PSTranscript_20191119_155424.txt
Cloning into 'repo'...
remote: Counting objects: 58975, done.
remote: Compressing objects: 100% (21457/21457), done.
remote: Total 58975 (delta 43348), reused 51727 (delta 37145)
Receiving objects: 100% (58975/58975), 70.46 MiB | 3.95 MiB/s, done.
Resolving deltas: 100% (43348/43348), done.
Checking out files: 100% (3878/3878), done.
Transcript stopped, output file is .\PSTranscript_20191119_155424.txt

And here's what is captured in the transcript, note that some of the git output is missing

**********************
Windows PowerShell transcript start
Start time: 20191119155424
Username: 
RunAs User: 
Configuration Name: 
Machine: 
Host Application: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Process ID: 20644
PSVersion: 5.1.17134.858
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17134.858
BuildVersion: 10.0.17134.858
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Transcript started, output file is .\PSTranscript_20191119_155424.txt
**********************
Windows PowerShell transcript end
End time: 20191119155457
**********************
like image 805
Zam Avatar asked Oct 15 '25 12:10

Zam


1 Answers

There's no reason to call Out-Default - just use your git command as-is, and your problem will go away: both its stdout and stderr streams will be transcribed.

git writes status information to stderr by default, and the - mistaken - use of Out-Default affects stderr output specifically, as described in the bottom section.

The following example demonstrates that both stdout and stderr output from external programs are captured in the transcript:

$file = [IO.Path]::GetTempFileName()

"--- DIRECT OUTPUT ---`n"

Start-Transcript $file

# Execute a command that produces
# both stdout and stderr output.
# Do NOT use Out-Default.
if ($env:OS -eq 'Windows_NT') {  # Windows
  cmd /c 'echo hi & nosuch'
} else {                         # macOS, Linux
  sh -c 'echo hi; nosuch'
}

Stop-Transcript

"`n--- CORE CONTENT OF TRANSCRIPT ---"

# Print the core of the transcript.
((Get-Content -Raw $file) -split '(?m)^\*+\s*$')[2]

Remove-Item $file

On Windows, you'll see something like the following, demonstrating that both streams were captured:

--- DIRECT OUTPUT ---

Transcript started, output file is C:\Users\jdoe\AppData\Local\Temp\tmp342C.tmp
hi
'nosuch' is not recognized as an internal or external command,
operable program or batch file.
Transcript stopped, output file is C:\Users\jdoe\AppData\Local\Temp\tmp342C.tmp

--- CORE CONTENT OF TRANSCRIPT ---

Transcript started, output file is C:\Users\jdoe\AppData\Local\Temp\tmp342C.tmp
hi
'nosuch' is not recognized as an internal or external command,
operable program or batch file.

The purpose of the Out-Default cmdlet:

Out-Default is not meant to be called from user code.

Instead, it is meant to be used only by PowerShell host applications, including by PowerShell itself. It creates pretty-printed string representations of the output objects using PowerShell's output-formatting system and sends them to the host for display.

The reason that it is a public cmdlet is that you are allowed to override it in order to define a custom output formatter, although doing so is rare.

Overriding is as simple as defining an advanced Out-Default function in your session, which must have the same parameter declarations and pipeline-binding behavior. You can scaffold such a function via a wrapper (proxy) function, as demonstrated in the bottom section of this answer). Note that in order to produce visible output from your function, you must send your custom-formatted strings either to the original Out-Default or use the host APIs to print them (Write-Host, in the simplest case).


Bug:

Your use of Out-Default - though ill-advised - should arguably still have worked.

While that is a moot point for Out-Default, given that it shouldn't be called directly, Out-Host exhibits the same problem (as of PowerShell Core 7.0.0-preview.6), and there are legitimate reasons to call Out-Host, namely to explicitly print to the display only (and doing so should not affect transcription behavior).

Specifically, if you use Out-Host explicitly, stderr output from external programs is unexpectedly not recorded in the transcript. (By contrast, the problem doesn't surface with PowerShell commands.)

The problem has been reported in GitHub issue #11134.

like image 168
mklement0 Avatar answered Oct 17 '25 02:10

mklement0



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!