"error: add_cacheinfo failed to refresh for path" with custom power shell merge driver

"error: add_cacheinfo failed to refresh for path" with custom power shell merge driver

我正在尝试编写一个自定义的 git 合并驱动程序 shell 但我已经“无所作为”失败了。即打开本地文件,将内容作为合并结果写回本地文件,并返回退出码0。

param (
    [Parameter(Mandatory=$true)][string]$baseFile,
    [Parameter(Mandatory=$true)][string]$localFile,
    [Parameter(Mandatory=$true)][string]$remoteFile
)

$PSDefaultParameterValues['*:Encoding'] = 'utf8'

(Get-Content $localFile) | Out-File $localFile
exit 0

我在 .git/config 添加了:

[merge "custom"]
    name = custom powershell merge driver
    driver = c:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -ExecutionPolicy RemoteSigned -Command ./mergeDriver.ps1 -baseFile %O -localFile %A -remoteFile %B

.git属性如下所示:

*.txt text
file.txt merge=custom

file.txt 是要合并的 utf8 文本文件。

每次我尝试 merge/cherry-pick 有冲突的文件时我得到 error: add_cacheinfo failed to refresh for path 'file.txt'; merge aborting.

示例存储库

我在 https://bitbucket.org/Deeem2031/mergedriver_test/src/master/ 创建了一个测试库 如果您克隆它并将更改添加到 .git/config 您应该能够通过 运行 git cherry-pick dbb40ba

重现该问题

我已经注意到的事情

如果您删除 $PSDefaultParameterValues['*:Encoding'] = 'utf8' 或根本不触摸文件,即删除 (Get-Content $localFile) | Out-File $localFile,则错误消失。

file.txt是否预先编码为utf8似乎并不重要。

https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/out-file 状态 Input objects are automatically formatted as they would be in the terminal, [...] 这确实意味着它可能会改变一些事情,但我能看到的唯一区别(即使使用十六进制编辑器)是在文件末尾添加了 CRLF。

我确实找到了这个答案 ,它听起来与我的问题非常相似,但我已经将结果写入 $localFile。

所以显而易见的问题是:为什么会发生此错误?

问题实际上出在合并驱动程序中,即mergeDriver.ps1

Git 的合同是合并驱动程序接收和写入的文件内容是“干净”的形式,即在你的情况下只有 LF(或者至少没有 CR/LF) 行尾。

但是,(Get-Content $localFile) | Out-File $localFile 不会保持文件内容不变,不管它看起来如何。原因是 $localFile 在您的情况下根本没有行结束。 hexdump -C 关于其内容是这样说的:

00000000  ef bb bf 76 65 72 73 69  6f 6e 20 3d 20 31 35 30  |...version = 150|

Out-File 追加一个CR/LF!

因此,如果您将合并驱动程序改为调用 Out-File -NoNewline,它将在没有 add_cacheinfo 错误消息的情况下工作。

也就是说,它将按预期工作:cherry-pick 会说没有任何更改,并询问您是否要提交(这需要 --allow-empty 选项)。