Powershell and german umlauts in git branch names

后端 未结 1 1899
忘了有多久
忘了有多久 2021-01-13 16:42

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 no

相关标签:
1条回答
  • 2021-01-13 17:02

    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...

    0 讨论(0)
提交回复
热议问题