【问题标题】:PowerShell ISE throws an error on git checkoutPowerShell ISE 在 git checkout 上抛出错误
【发布时间】:2015-01-08 10:24:13
【问题描述】:

在 PowerShell 中,git checkout 运行时没有任何错误消息。在 ISE 中,虽然git checkout 仍然有效,但 ISE 会给出错误消息。

> 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

这不是大问题,因为git checkout 仍然有效。不过,这很烦人,所以我想知道为什么 ISE 会在标准 PowerShell 不抱怨时抱怨,重要的是,我们如何防止这种烦恼。

我查看了Why is Powershell ISE showing errors that Powershell console does not show?,它解释说 ISE 只是显示正常外壳所经历的情况。该答案并未解释如何平息这种烦人的行为。

【问题讨论】:

  • 似乎 ise 确实对 powershell 没有的 stderr 输出做出反应,也许看看这个问题的答案:stackoverflow.com/questions/1394084/… 如果您不希望显示错误,您可以将 stderr 重定向到 $像这样2> $null
  • Should/Could this question be re-written 以表示由于 Git 将错误输出流用于其大部分输出(不仅仅是用于结帐),它在任何主机中看起来都很糟糕(不仅仅是ISE)?

标签: git powershell powershell-3.0 powershell-ise


【解决方案1】:

looks like 您现在可以通过简单地设置环境变量将 stderr 重定向到整个 powershell 脚本中的 stdout:

$env:GIT_REDIRECT_STDERR = '2>&1'

【讨论】:

    【解决方案2】:

    @BartekB 出色答案的配置文件功能化版本...

    function Invoke-Git {
    <#
    .Synopsis
    Wrapper function that deals with Powershell's peculiar error output when Git uses the error stream.
    
    .Example
    Invoke-Git ThrowError
    $LASTEXITCODE
    
    #>
        [CmdletBinding()]
        param(
            [parameter(ValueFromRemainingArguments=$true)]
            [string[]]$Arguments
        )
    
        & {
            [CmdletBinding()]
            param(
                [parameter(ValueFromRemainingArguments=$true)]
                [string[]]$InnerArgs
            )
            C:\Full\Path\To\git.exe $InnerArgs
        } -ErrorAction SilentlyContinue -ErrorVariable fail @Arguments
    
        if ($fail) {
            $fail.Exception
        }
    
    }
    
    # Could shorten the function name. I instead alias it, for terseness.
    Set-Alias -Name git -Value Invoke-Git
    
    # Also alias the name with the extension, as it is called by some applications this way.
    Set-Alias -Name git.exe -Value Invoke-Git
    

    【讨论】:

    • 另外我添加了Function git() { Invoke-Git @args },这样我就可以正常使用git了。
    • 可以重命名函数或给它取别名。我将在脚本示例中添加别名行。
    • git.exe 创建别名会导致无限循环(因为您在Invoke-Git 上使用它)。仅使用 git 的别名很好,不会引起问题。
    • 哈!接得好。这不会发生在我的个人资料中,因为我在函数中使用了 Git 的完整路径。我会在这里提出同样的建议。
    • @NathanHartley 您应该补充一点,在 ISE 中,您仍然需要在调用 Invoke-Git 后检查 $LASTEXITCODE。例如,对于我来说,在 ISE 的 git clone 中,fail 变量在克隆后永远不会为空(尽管它有效),但 $LASTEXITCODE0,因此可以忽略失败。作为最后一次检查if ($LASTEXITCODE -ne 0 -and $fail) { throw $fail.Exception },我能够修复它。这样我可以抛出真正的 git 错误
    【解决方案3】:

    如指定here, 在安静命令后添加-q 不会显示此类错误。

    【讨论】:

      【解决方案4】:

      有几种方法可以避免这些错误,它们看起来或感觉都不是“自然”的。 第一个使用错误流重定向和一些围绕错误的逻辑:

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

      其次取决于ErrorAction,它仅适用于PowerShell构造,因此我们需要先构建一个:

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

      在我的ISEGit 模块中,我使用后者来避免错误记录以不受控制的方式“泄露”给最终用户。

      最后,您可以“修复它”(好吧,整理一下...),方法是确保最后可以使用字符串:

      "$(git ? 2>&1 )"
      

      或者我会投反对票,因为它会让你不知道任何 实际 错误,将全局 $ErrorActionPreference 设置为 SilentlyContinue - 尽管这与将错误流重定向到 $null 没有什么不同.

      【讨论】:

      • 如果您有机会在示例 2 中展示如何调用它的快速示例。
      猜你喜欢
      • 2018-06-29
      • 1970-01-01
      • 2016-12-04
      • 2015-10-05
      • 1970-01-01
      • 2020-11-03
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多