首页 > 解决方案 > git 分支名称中的 Powershell 和德语变音符号

问题描述

我编写了一个批处理文件,它使用 powershell 命令删除所有本地 git 分支,但要保留的分支除外。如果分支名称中使用了德语变音符号,则它不起作用。

切换到分支'master'

你的分支是最新的'origin/master'。

删除了分支 DEV_API_StartenDesWorkers(原为 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

标签: gitpowershellbatch-fileencoding

解决方案


免责声明:我绝不是这方面的专家 - 下面的答案为我解决了症状,但您的里程可能会有所不同。其他对 Windows 代码页等有更深入了解的人可能会给出更好的答案......

根据我的阅读,问题的核心是 git 正在将其输出写入 utf8,正如 @lorek 和 @LeGEC 在评论中所指出的那样,但它被命令提示符使用的 Windows 代码页破坏了。

您可以在使用和不使用 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

就我而言,神奇的“编码 437”是通过调用chcp来获取 shell 的当前代码页来确定的:

C:\> chcp
Active code page: 437

chcp的文档告诉我 437 是United States.

对我来说似乎解决这个问题的是使用代码页 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).

希望这会有所帮助...


推荐阅读