Search code examples
gitpowershellpowershell-3.0powershell-ise

PowerShell ISE throws an error on git checkout


In PowerShell, git checkout runs without any error message. In the ISE, while git checkout stills works, the ISE gives an error message.

> git checkout master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
git : Switched to branch 'master'
At line:1 char:1
+ git checkout master
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Switched to branch 'master':String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

This isn't a major problem, because git checkout still works. It's annoying, though, so I'd like to know why the ISE complains when the standard PowerShell doesn't, and importantly, how can we prevent this annoyance.

I have looked at Why is Powershell ISE showing errors that Powershell console does not show?, which explains that the ISE is just displaying what the normal shell is experiencing. That answer does not explain how to quiet down this annoying behavior.


Solution

  • There are few ways you can avoid these errors, none of them looks or feels 'natural'. First one uses error stream redirection and some logic around errors:

    $out = git ? 2>&1
    if ($?) {
        $out
    } else {
        $out.Exception
    }
    

    Second depends on the ErrorAction, that is available only for PowerShell constructs, so we need to build one first:

    & {
        [CmdletBinding()]
        param()
    
        git ?
    } -ErrorAction SilentlyContinue -ErrorVariable fail
    
    if ($fail) {
        $fail.Exception
    }
    

    In my ISEGit module I use latter to avoid error records 'leaking' to end user in uncontrolled manner.

    Finally you can 'fix it' (well, sort off...) by making sure you can a string in the end:

    "$(git ? 2>&1 )"
    

    Or something I would vote against as it will leave you unaware of any actual errors, setting global $ErrorActionPreference to SilentlyContinue - though this is not different from redirecting error stream to $null.