bash - 如何在 Powershell(vs bash)中正确生成和应用 git 补丁?

标签 bash git powershell newline

请注意以下简短场景(在 Powershell 中):

PS> git diff -U3 -r -M HEAD -- .\Metadata\LegacyTypeModules\xyz.Web.Main.draft.json | Out-File -Encoding ascii c:\temp\1.diff

PS> git apply --cached C:\temp\1.diff
error: patch failed: Metadata/LegacyTypeModules/xyz.Web.Main.draft.json:69
error: Metadata/LegacyTypeModules/xyz.Web.Main.draft.json: patch does not apply

这会失败,因为文件中的最后一行不以 CRLF 结尾: enter image description here

但是,在 bash 中运行时,完全相同的命令可以工作:

$ git diff -U3 -r -M HEAD -- Metadata/LegacyTypeModules/xyz.Web.Main.draft.json > /c/Temp/2.diff

$ git apply --cached /c/Temp/2.diff

P11F70F@L-R910LPKW MINGW64 /c/xyz/tip (arch/1064933)

这两个补丁的区别是: enter image description here

所以问题似乎发生了,因为 Powershell 使用 CRLF 终止通过管道的每一行,而 bash 保留原始行结尾。

我理解为什么会发生这种情况 - Powershell 使用对象进行操作,并且对象是字符串不包括 EOL 字符。写入文件时,Powershell 将对象转换为字符串(在字符串的情况下,转换是 nop)并使用默认的 EOL 序列来分隔行。

是不是说Powershell根本不能用在EOL敏感的场景中?

最佳答案

确实:

  • PowerShell 总是将外部程序的输出 解码为文本(使用 [Console]::OutputEncoding)

  • 然后,当行可用时,它逐行通过管道发送解码的输出。

  • 文件输出 cmdlet,例如 Out-File然后总是使用 platform-native 换行序列 - Windows 上的 CRLF - 在写入目标文件时终止每个(字符串化)输入对象(使用 its 默认字符编码(或通过 -Encoding 指定的那个),这在技术上与用于解码外部程序输出的编码无关)。

换句话说:PowerShell 管道(和重定向)支持通过传递原始二进制数据,从 PowerShell 7.2 开始 - future 的原始-GitHub issue #1908 中正在讨论数据支持。 .

解决方法:

  • 手动使用 LF 换行符 ("`n") 加入和终止解码的输出行,并按原样写入生成的多行字符串 ( -NoNewLine) 到目标文件,如zdan's helpful answer所示.

  • 在这个简单的例子中,委托(delegate)给 cmd.exe/c 是最简单的,因为 cmd.exe 的管道和重定向原始字节管道:

cmd /c @'
git diff -U3 -r -M HEAD -- .\Metadata\LegacyTypeModules\xyz.Web.Main.draft.json > c:\temp\1.diff
'@

注意 here-string 的使用为了任何嵌入式引用的可读性和易用性(此处不适用)。

关于bash - 如何在 Powershell(vs bash)中正确生成和应用 git 补丁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70283579/

相关文章:

linux - 使用 netcat (nc) 作为 HTTP 代理服务器和监视器

git - 如何控制提交 Hook 自动推送到 git 目标 repo 的文件的所有权?

powershell - 通过 Invoke-Command : "... not recognized as the name..." 调用远程 cmdlet (ffmpeg)

powershell - PowerShell-将计算的属性与另一个选定字段连接

bash - 使用 bash 进行动态 zip 文件校验和检查

如果命令行输出不包含字符串,则发送邮件的 Bash 脚本

macos - 在 "find"中使用运算符

git 在推/pull 时加密/解密远程存储库文件

git - 两个 git 提交具有相同 `abbrev-commit` 的机会是多少

powershell - 哈希表中的解释点