git - 从 PowerShell 脚本中提取时出错
问题描述
我有一个简单的 PowerShell 脚本,可以让文件夹与它的 git 存储库保持同步。
Param(
[Parameter(Mandatory = $true)][string]$branch,
[string]$location,
[int]$depth
)
Get-ChildItem -Recurse -Directory -Depth $depth -Filter _$branch -Name -Path $location |
ForEach-Object {
Write-Output "`n$("{0:MM/dd/yy} {0:HH:mm:ss}" -f (Get-Date)): Getting latest from $location$_"
git -C $location$_ pull
} *>> logs\$branch.log
当存储库已经是最新的时,它可以正常工作。但是,如果不是,这是输出:
07/29/19 14:47:27:从 somepath 获取最新信息 git:来自 https://gitlab.com/someplace 在某个地方\UpdateBranch.ps1:10 char:5 + git -C $location$_ 拉 + ~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (来自 https://gi...n/somerepo:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError b34e5d0..3ec9561 开发 -> 起源/开发 b6d33b1..65fb520 特征/特征1 -> 原点/特征/特征1 * [新分支] feature/feature2 -> origin/feature/feature2 c3fe1c9..9553b72 主 -> 原点/主 更新 b34e5d0..3ec9561 快进 样式表.scss | 4++-- ... 6 个文件更改,11 个插入(+),10 个删除(-)
它似乎进行了更新,但也输出了错误。
解决方案
Git 将更详细的数据写入错误流,以允许解析器解析最重要的位。然后,这些解析器可以忽略对人类用户意味着的更详细的输出。该数据通过 stderr 流发送。Powershell 默认将 stderr 上的数据转换为错误记录,抛出你看到的错误。
似乎最简单的一个是添加--porcelain
or --quiet
,它不会将详细数据写入 stderr 或根本没有数据。
git checkout branch --porcelain
git checkout branch --quiet
另一种选择是通过环境为 git 配置标准重定向模式,至少这样您不需要将重定向分散在整个代码中:
$env:GIT_REDIRECT_STDERR = '2>&1'
在这个 StackOverflow 答案中找到了更多选项,强制所有重定向消息到它们的字符串表示也很好:
git checkout branch 2>&1 | %{ "$_" }
另一种语法是:
"$(git checkout branch ? 2>&1 )"
另一种解决方法是通过以下方式调用 git cmd
:
& cmd /c 'git checkout branch 2>&1'
在这个答案中,您将找到一个以干净方式调用 git 的包装函数。
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
推荐阅读
- ruby-on-rails - 模型无效,因为创建时外键不存在
- aws-lambda - 触发错误时,New Relic 不会为进程调度 NRQL 警报条件
- sql - 错误:值 show 不是 Unit CaseFileDFTemp.show() 的成员
- javascript - 如何根据jQuery数据表中返回的数据默认选择下拉值
- excel - vba中如何判断单选框是否被选中
- vue.js - Vue 组件样式未在 Puppeteer 中加载
- react-native - 将动态文件名导入 React-Native
- redis - 在 JEDIS 中增加池大小会影响 redis 性能吗?
- git - 有没有办法让 GIT 通过历史跟踪重命名的文件
- mysql - 使用 Fetch API 使用效果删除一行 - ReactJS