PowerShell和Git分支名称中的德语umlauts

4

我编写了一个批处理文件,使用powershell命令删除除一个保留分支外的所有本地git分支。如果分支名称中使用了德语umlauts,则无法正常工作。

切换到分支'master'

您的分支已经是'origin/master'最新版。

已删除分支DEV_API_StartenDesWorkers(was 61bec6d883b)。

错误:未找到分支'DEV_Üersicht_Drucken'。

错误:未找到分支'test_pr├â•�fung'。

正确的名称是DEV_Übersicht_druckentest_prüfung

如何实现删除这些分支?

这是脚本:

@echo off
set KEEP=%1
IF [%KEEP%] == [] (goto eof)

git checkout %KEEP%

powershell "git branch -D @(git branch | select-string -NotMatch %KEEP% | ForEach-Object {$_.Line.Trim() })"

:eof

Git通常认为所有字符串都是UTF-8编码的。Windows通常喜欢使用UTF-16-LE编码。它们之间产生了冲突,一方胜出,另一方失败。 :-) 更加严肃地说,(但我不使用Windows,也没有PowerShell):你可能需要找到某种方法来使你的脚本输出UTF-8编码形式。 - torek
你的shell存在编码问题。为了缩小问题范围:你能否在powershell.exe中运行你命令中的(git branch | ...)部分? - LeGEC
作为入门建议,我建议停止从批处理脚本中运行 PowerShell 命令。 - Ansgar Wiechers
1
如果可能的话,我会直接运行PowerShell脚本,而不使用批处理文件;批处理文件起源于上世纪80年代,当时还没有UTF-8,而cmd.exe在上世纪90年代出现,但UTF-8在2000年代变得流行起来... - aschipfl
1个回答

3

免责声明:我绝不是这方面的专家——以下答案为我解决问题的经验,但你的情况可能会有所不同。对于Windows代码页等更深层次的知识更熟悉的人可能会有更好的答案…

据我所了解,问题的核心在于git以utf8编写其输出,正如@lorek和@LeGEC在评论中指出的一样,但它却被命令提示符使用的Windows代码页所损坏。

您可以使用PowerShell或不使用PowerShell来重现此行为:

c:\repo> git status
On branch test_prüfung
nothing to commit, working tree clean

c:\repo> git branch
* test_pr<C3><BC>fung

c:\repo> git branch | more
* test_pr├╝fung

c:\repo> powershell "$x = git branch; write-host $x"
* test_pr├╝fung

c:\repo> powershell "git branch -D @(git branch | select-string -NotMatch master | ForEach-Object {$_.Line.Trim() })"
error: branch '* test_pr├╝fung' not found.

正在发生的是git将其输出编码为UTF8字节,然后shell使用不同的编码对其进行解码 - 类似于这样:
$branch = "test_prüfung";
$utf8 = [System.Text.Encoding]::Utf8.GetBytes($branch);
$mangled = [System.Text.Encoding]::GetEncoding(437).GetString($utf8);
write-host $mangled

其输出结果为:

test_pr├╝fung

在我的情况下,通过调用chcp来获取shell当前的代码页,确定了神奇的“编码437”。
C:\> chcp
Active code page: 437

根据 chcp 的文档,437 是表示美国的代码页。

对我而言,似乎可以解决这个问题的方法是使用代码页 65001(即 UTF8),那么你就会得到:

C:\repo> chcp 65001
Active code page: 65001

c:\repo> powershell "$x = git branch; write-host $x"
* test_prüfung

这个现在也正常工作了:

c:\repo> powershell "git branch -D @(git branch | select-string -NotMatch master | ForEach-Object {$_.Line.Trim() })"
Deleted branch test_prüfung (was 1e9bc02).

希望这能有所帮助...

非常感谢!chcp 65001是拼图中缺失的一块! :-) - MadMG

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