4

In my profile, I've customised the prompt via the prompt function to embed git branch information:

function prompt
{
    $prefix = ""
    if ((test-path ".git") -or (test-path ".gitdir") -or ((git rev-parse --is-inside-work-tree 2> $null) -eq "true")) {
        $prefix = "[git:" + (& git symbolic-ref --short HEAD) + "]"
    }

    write-host "PS $prefix $(get-location) >" -nonewline -foregroundcolor DarkMagenta
    return " "
}

The problem however is that when I'm outside of a git tree, the git rev-parse part of the check inserts an error into $error even though I'm redirecting errors to $null.

This means that $error gets polluted with the following error, as it is generated every time the prompt renders:

git : fatal: Not a git repository (or any of the parent directories): .git
At C:\temp\prompt.ps1:4 char:64
    + ... ".gitdir") -or ((git rev-parse --is-inside-work-tree 2> $null) -eq "t ...
    +                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (fatal: Not a gi...ectories): .git:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Running interactively I've noticed that the 2> $null does suppress the error to the console, but the error still appears in $error:

PS C:\temp> $error
PS C:\temp> git rev-parse --is-inside-work-tree 2> $null
PS C:\temp> $error
git : fatal: Not a git repository (or any of the parent directories): .git
At line:1 char:1
+ git rev-parse --is-inside-work-tree 2> $null
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (fatal: Not a gi...ectories): .git:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

PS C:\temp>

I've tried wrapping the command in try {...} catch {}, and also using invoke-command with an erroraction of ignore, both with no luck:

PS c:\temp> $error.clear()
PS c:\temp> $error
PS c:\temp> invoke-command -scriptblock { git rev-parse --is-inside-work-tree 2> $null } -erroraction ignore
PS c:\temp> $error
git : fatal: Not a git repository (or any of the parent directories): .git
At line:1 char:31
+ ... d -scriptblock { git rev-parse --is-inside-work-tree 2> $null } -erro ...
+                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (fatal: Not a gi...ectories): .git:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

PS c:\temp> $error.clear()
PS c:\temp> $error
PS c:\temp> try { git rev-parse --is-inside-work-tree 2> $null } catch { }
PS c:\temp> $error
git : fatal: Not a git repository (or any of the parent directories): .git
At line:1 char:7
+ try { git rev-parse --is-inside-work-tree 2> $null } catch { }
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (fatal: Not a gi...ectories): .git:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

PS c:\temp>

How can I suppress this error from adding to $error so it stays clean?

5
  • if you change 2> $Null to 2>$Null it seems to work for me. note the removal of the space between the > and the $. [grin] Commented May 31, 2019 at 10:26
  • @Lee_Dailey - removing the space hasn't worked for me, unfortunately. Commented May 31, 2019 at 10:35
  • well, now the space makes no difference. [blush] i don't know what i was doing earlier that made it seem to work differently. ///// however, when i use your code [git rev-parse --is-inside-worktree 2> $Null] on my win7, ps5.1, git version 2.21.0.windows.1 setup, the error is suppressed. Commented May 31, 2019 at 10:48
  • I'm on Win10, PS 5.1, git 2.11.1.windows.1 Commented May 31, 2019 at 10:56
  • perhaps it would help to upgrade your git-for-windows installation? Commented May 31, 2019 at 11:13

1 Answer 1

5

Unfortunately, as of PowerShell Core 6.2.1 / Windows PowerShell v5.1, using 2>$null to suppress stderr output from an external program unexpectedly still takes a detour via Powershell's error stream (stream 2), so the output is still recorded in $Error. This known problem is described in this GitHub issue.

As a workaround, you can call git via cmd /c (or sh -c on Unix) and let it do the redirection:

# Windows
cmd /c 'git rev-parse --is-inside-work-tree 2>NUL'

# Linux, macOS
sh -c 'git rev-parse --is-inside-work-tree 2>/dev/null'

As you state, this will correctly pass git's exit code through so you can determine success via $LASTEXITCODE afterwards.

Sign up to request clarification or add additional context in comments.

1 Comment

Excellent - ta. Also happy to see that cmd propagates the truthy success so working nicely in an if.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.