I have written a batch file which uses a powershell command to delete all local git branches except one to keep. If there are german umlauts used in branch names, it does not work.
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.
Deleted branch DEV_API_StartenDesWorkers (was 61bec6d883b).
error: branch 'DEV_Üersicht_Drucken' not found.
error: branch 'test_pr├�fung' not found.
The correct names are DEV_Übersicht_drucken
and test_prüfung
.
How can I achieve to delete these branches too?
This is the script:
@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
Disclaimer: I'm by no means an expert in this stuff - the answer below fixes the symptoms for me, but your mileage may vary. Someone else with deeper knowledge of Windows codepages and the like might be able to give a better answer...
From what I've read, the core of the problem is that git is writing its output in utf8 as noted by @lorek and @LeGEC in the comments, but it's being mangled by the Windows codepage in use by the command prompt.
You can reproduce the behaviour with and without 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.
What's happening is git is encoding its output into utf8 bytes and then the shell is decoding that using a different encoding - something like this:
$branch = "test_prüfung";
$utf8 = [System.Text.Encoding]::Utf8.GetBytes($branch);
$mangled = [System.Text.Encoding]::GetEncoding(437).GetString($utf8);
write-host $mangled
which outputs:
test_pr├╝fung
In my case, the magic "encoding 437" was determined by calling chcp
to get the shell's current codepage:
C:\> chcp
Active code page: 437
And the documentation for chcp tells me that 437 is the codepage for United States
.
What seems to fix the issue for me is to use codepage 65001 (i.e. UTF8) and then you get:
C:\repo> chcp 65001
Active code page: 65001
c:\repo> powershell "$x = git branch; write-host $x"
* test_prüfung
And this now works fine too:
c:\repo> powershell "git branch -D @(git branch | select-string -NotMatch master | ForEach-Object {$_.Line.Trim() })"
Deleted branch test_prüfung (was 1e9bc02).
Hope this helps a little bit...