git diff 命令在 Powershell 中的输出未被正确处理

7

我已经阅读了几篇与此问题相关的问答,但没有提供答案。有一个解决方法,我在这里再次说明,但我想要理解和解决这个问题。

问题

问题是,在powershell中执行命令git diff reva revb | Out-File mypatch.patch会产生“垃圾字符”,例如将德语umlauts(ä)替换为(├ñ)。

调查

当我执行建议中的$Env:LESSCHARSET="utf8"时,终端中确实能得到正确的输出,但一旦将其重定向到文件mypatch.patch中,umlauts(和其他字符)就被破坏了。即使使用git --no-pager diff reva revb也能在终端中得到正确的输出。但是,只要你想将其传输到文件中,它就是错误的。你看到的不是你得到的!

对我来说,Out-File的输入已经被破坏,因此设置-Encoding参数不会改变任何东西。我不认为Out-File应该承担责任。例如,命令$mypatch = git diff reva revb(即使在diff之前添加了--no-pager)会导致变量中的Euro符号或umlauts出现损坏(Ôé¼而不是€),当该变量被打印到终端时。

我尝试过Windows 10(1709)上的powershell 5.1和开源powershell core 6.0.4。我使用git 2.18.0.windows.1。与Windows命令行(cmd)一起使用没有问题,因此简单的解决方法是从powershell控制台调用:

解决方法

cmd /c "git diff reva revb > mypatch.patch"

问题

如何仅通过powershell解决此问题?


你尝试避免使用管道吗?Out-File -InputObject (git diff reva revb) -Path mypatch.patch -Encoding utf8 - DarkLite1
从视觉上看,可能会避免使用管道,但它仍将在后台中使用。我怀疑结果将是相同的。 - Matt
你可以使用 git diff reva revb | Out-File -Encoding "UTF8" mypatch.patch 命令,但是这会生成一个带有 BOM(字节顺序标记)的文件。如果不想要 BOM,则可以使用 $Utf8NoBom = New-Object System.Text.UTF8Encoding $False; [System.IO.File]::WriteAllLines($MyPath, $MyFile, $Utf8NoBom) 命令。 - Theo
@DarkLite1 这并没有解决问题。 - Andreas
1个回答

5

这个问题似乎是由于 [Console]::OutputEncoding 设置错误导致的。如果它没有设置为 UTF8,请尝试进行设置:[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

如果您使用 $Env:LESSCHARSET,那也没关系,我认为它已经不再使用了。


2
相反,在我的机器上,仅使用$Env:LESSCHARSET修复就足以使git diff的输出正确呈现。OutputEncoding设置不会有任何影响,但无法解决特殊字符乱码的问题(例如,<C3><BC>而不是ü)。 - ojdo
1
正如我所说的,它在终端中被正确呈现,但如果将输出重定向到文件中,它就是垃圾,只有那个答案中的设置才能解决我的问题。 - Andreas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接