53093


PowerShellでGitのログ出力を加工しようとしたのですが、日本語が文字化けしてしまいます。  
文字化けしないようにするにはどうしたら良いのでしょうか。

以下、現象の発生するコード例です。

[code]

    Invoke-Expression "git log --oneline" | Select-Object -First 5
    
[/code]

* * *

### 試したこと

`$env:LANG = "ja_JP.UTF-8"` を実行することで `git log`
単体実行での文字化けは治るのですが、パイプ処理や、リダイレクトでファイル出力すると、同様の文字化けが発生してしまいます。

* * *

### 環境

  * Windows10 Pro 64bit (1809)
  * PowerShell version 5.1.17763.316
  * git version 2.18.0.windows.1


CC BY-SA 4.0
2019-02-27T04:15:52.680
53061
2019-02-28T10:28:47.907
2019-02-28T10:28:47.907
14817
14817
question
git powershell 文字化け
PowerShell処理でgitログが文字化けする


以下の２通りの方法で文字化けなく処理できるようになりました。

* * *

### 方法1: [Console]::OutputEncoding に UTF8 を指定する

[code]

    $enc = [Console]::OutputEncoding
    try
    {
        [Console]::OutputEncoding = [Text.Encoding]::UTF8
        Invoke-Expression "git log --oneline" | Select-Object -First 5
    }
    finally
    {
        [Console]::OutputEncoding = $enc
    }
    
[/code]

* * *

### 方法2: nkf で SJIS に変換する

`nkf32.exe` を入手し、gitコマンド出力をSJISに変換するバッチファイル(git_sjis.bat)を作る。

[code]

    @echo off
    git %1 %2 %3 %4 %5 %6 %7 %8 %9 | nkf32.exe -s
    
[/code]

[code]

    Invoke-Expression ".\git_sjis.bat log --oneline" | Select-Object -First 5
    
[/code]


CC BY-SA 4.0
2019-02-27T16:24:59.080
53074
2019-02-27T16:52:49.543
2019-02-27T16:52:49.543
14817
14817
53061
answer


一般論として、特にリダイレクトはあくまでバイト列を送受信するものであり、送り側と受け側での合意がなければやり取りできません。更にUNIX系ツールでは送受信されるデータを関与していないものが多いです。  
ところがWindowsでは状況がかなり異なります。基本的にコントロールパネルで設定されたエンコーディングでテキストデータがやり取りされていることを前提としています。その際、日本語においてはShift_JISしか設定できません。  
またPowerShellなどの多くのアプリケーションは受け取ったテキストをUnicodeに変換して処理するためエンコーディングが非常に重要となります。

以上を踏まえて、送り側と受け側とでどのようなバイト列とするかをプログラムの組み合わせ毎に設計する必要があります。

* * *

質問では、`git`がログメッセージを出力し、`PowerShell`がその文字列を受け取ることとなっています。neeさんからも回答がありますが、それ以外にも方法があって、例えば`git
log`コマンドには[`--encoding`オプション](https://git-scm.com/docs/git-log#git-log---
encodingltencodinggt)が存在します。環境変数`LANG`は特に設定せず

[code]

    Invoke-Expression "git log --encoding=Shift_JIS --oneline" | Select-Object -First 5
    
[/code]

とやる方法もあります。

もちろん個別に指定するのではなく`i18n.logOutputEncoding`設定でデフォルト値を変更することもできます。ただし、`git`コマンドは`PAGER`を呼び出したりといろいろなプログラムと組み合わせるため、先に述べた通り、どのプログラムとどのプログラムをどのエンコーディングでやり取りするかを検討しなければなりませんので、万能な回答は難しいです。

* * *

neeさんの回答に`[Console]::OutputEncoding`を使った方法が挙げられていますが、罠があるため指摘しておきます。もちろん、送り側・受け側でUTF-8を使用するのは選択肢の一つとして正しいです。しかし、`[Console]::OutputEncoding`を変更するとそれに従ってコンソールのフォントも変更されます。手元の環境では`Consolas`に変更されました。この状態ですとプログラム間は正しくテキストをやり取りできていますが、コンソールが日本語を表示できません。一度、フォント設定を`MSゴシック`等に変更することで解消されますが、設定を行っていない環境では文字化けが解消していないかのような誤解を与えますのでお気を付けください。


CC BY-SA 4.0
2019-02-28T07:52:49.130
53093
2019-02-28T08:15:40.227
2019-02-28T08:15:40.227
4236
4236
53061
answer