157

gitでVirtualPC仮想マシンファイル(* .vmc)を追跡していますが、変更を加えた後、gitはファイルをバイナリとして識別し、差分を取得しませんでした。ファイルがUTF-16でエンコードされていることを発見しました。

このファイルがテキストであることを認識し、適切に処理するようにgitに教えることはできますか?

私はCygwinでgitを使用しており、core.autocrlfをfalseに設定しています。必要に応じて、UNIXでmSysGitまたはgitを使用できます。

4

9 に答える 9

92

私はしばらくの間この問題に苦しんでいて、ちょうど(私にとって)完璧な解決策を発見しました:

$ git config --global diff.tool vimdiff      # or merge.tool to get merging too!
$ git difftool commit1 commit2

git difftoolと同じ引数を取りますgit diffが、組み込みのGNUの代わりに選択したdiffプログラムを実行しますdiff。したがって、マルチバイト対応のdiff(私の場合vimはdiffモード)を選択し、git difftoolの代わりに使用しgit diffます。

「difftool」が長すぎて入力できないと思いませんか?問題ない:

$ git config --global alias.dt difftool
$ git dt commit1 commit2

Gitは揺れる。

于 2009-08-19T15:55:47.223 に答える
73

Unicesには、箱から出してすぐに機能する非常にシンプルなソリューションがあります。

たとえば、Appleの.stringsファイルでは次のようになります。

  1. .gitattributes次のコマンドを使用して、リポジトリのルートにファイルを作成します。

     *.strings diff=localizablestrings
    
  2. ~/.gitconfigファイルに以下を追加します。

     [diff "localizablestrings"]
     textconv = "iconv -f utf-16 -t utf-8"
    

ソースGitのDiff .stringsファイル(および2010年以降の古い投稿)。

于 2014-01-09T12:42:45.740 に答える
43

.gitattributesテキストファイルとして扱うように設定してみましたか?

例えば:

*.vmc diff

詳細については、http://www.git-scm.com/docs/gitattributes.htmlをご覧ください。

于 2009-04-22T16:42:22.537 に答える
32

デフォルトでは、gitUTF-16ではうまく機能しないようです。このようなファイルの場合、CRLF処理が行われていないことを確認する必要がありますがdiffmerge通常のテキストファイルとして機能する必要があります(これは、端末/エディターがUTF-16を処理できるかどうかを無視します)。

しかし、.gitattributesマンページを見ると、次のようなカスタム属性がありbinaryます。

[attr]binary -diff -crlf

.gitattributesしたがって、トップレベルでカスタム属性を定義できるように思われますutf16(テキストとして扱われるように、ここにマージを追加することに注意してください)。

[attr]utf16 diff merge -crlf

.gitattributesそこから、次のようなファイルを指定できます。

*.vmc utf16

また、次のバイナリであると考えているdiff場合でも、ファイルを作成できるはずであることに注意してください。git

git diff --text

編集

この答えは基本的に、GNUとUTF-16またはUTF-8の差分はあまりうまく機能しないことを示しています。git別のツールを使用して(を介して)違いを確認したい場合、その答えはGuiffy--ext-diffを示唆しています。

しかし、おそらく必要なのはdiff、ASCII文字のみを含むUTF-16ファイルだけです。--ext-diffこれを機能させる方法は、次のシェルスクリプトを使用することです。

#!/bin/bash
diff <(iconv -f utf-16 -t utf-8 "$1") <(iconv -f utf-16 -t utf-8 "$2")

UTF-8への変換はマージにも機能する可能性があることに注意してください。これは、双方向で行われることを確認する必要があります。

UTF-16ファイルのdiffを見るときの端末への出力については、次のようになります。

そのように差分をとろうとすると、バイナリのゴミが画面に吐き出されます。gitがGNUDiffを使用している場合、GNUDiffはUnicodeに対応していないように見えます。

GNU diffは実際にはユニコードを気にしないので、diff --textを使用すると、テキストを差分して出力するだけです。問題は、使用している端末が、発行されたUTF-16(ASCII文字である差分マークと組み合わせて)を処理できないことです。

于 2009-04-22T16:40:54.583 に答える
11

gitは最近、utf16などのエンコーディングを理解し始めました。gitattributes docsを参照して、検索してくださいworking-tree-encoding

[これはまったく新しいので、manページが一致していることを確認してください!]

(たとえば)ファイルがWindowsマシンでBOMなしのUTF-16である場合は、ファイルに追加し.gitattributesます

*.vmc text working-tree-encoding=UTF-16LE eol=CRLF

* nix上のUTF-16(bom付き)の場合、次のようになります。

*.vmc text working-tree-encoding=UTF-16-BOM eol=LF

(処理する必要のあるタイプファイルを置き換え*.vmcます)*.whateverwhatever

参照:working-tree-encoding「UTF-16LE-BOM」のサポート


後で追加

@Hackslashに続いて、これでは不十分であることがわかる場合があります

 *.vmc text working-tree... 

素敵なテキスト差分を取得するには、必要です

 *.vmc diff working-tree...

両方を置くことも同様に機能します

 *.vmc text diff working-tree... 

しかし、それは間違いなく

  • 冗長—eol=...意味text
  • Verbose —大規模なプロジェクトでは、数十の異なるテキストファイルタイプを簡単に作成できます。

問題

Gitには、を意味するマクロ属性 があります。逆は組み込みでは利用できませんが、gitはそれを合成するためのツール(私は思う!)を提供しますbinary-text -diff+text +diff

ソリューション

Gitを使用すると、新しいマクロ属性を定義できます。

私は.gitattributesあなたが持っているファイルの一番上を提案します

 [attr]textfile text diff

次に、textとdiffである必要があるすべてのパスに対して

 path textfile working-tree-encoding= eol=...

ほとんどの場合、デフォルトのエンコーディング(utf-8)とデフォルトのeol(ネイティブ)が必要になるため、削除される可能性があることに注意してください。

ほとんどの行は次のようになります

*.c textfile
*.py textfile
Etc

なぜdiffを使用しないのですか?

実用的:ほとんどの場合、ネイティブeolが必要です。つまり、ありませんeol=...。したがってtext、暗示されることはなく、明示的に配置する必要があります。

概念:テキストとバイナリは基本的な違いです。eol、encoding、diffなどはその一部にすぎません。

免責事項

私たちが住んでいる奇妙な時代のために、私は現在動作しているgitを備えたマシンを持っていません。そのため、現時点では最新の追加を確認できません。誰かが何か間違ったことを見つけたら、私は修正/削除します。

于 2019-02-14T05:02:18.513 に答える
8

解決策は、をフィルタリングすることcmd.exe /c "type %1"です。cmdのtypeビルトインが変換を行うため、git diffのtextconv機能を使用して、UTF-16ファイルのテキスト差分を有効にすることができます(テストされていませんが、UTF-8でも機能するはずです)。

gitattributesのマニュアルページからの引用:


バイナリファイルのテキスト差分の実行

一部のバイナリファイルのテキスト変換バージョンの差分を確認することが望ましい場合があります。たとえば、ワードプロセッサドキュメントをASCIIテキスト表現に変換し、テキストの差分を表示することができます。この変換によって一部の情報が失われますが、結果のdiffは人間が見るのに役立ちます(ただし、直接適用することはできません)。

textconv configオプションは、このような変換を実行するためのプログラムを定義するために使用されます。プログラムは、変換するファイルの名前である単一の引数を取り、結果のテキストをstdoutに生成する必要があります。

たとえば、バイナリ情報の代わりにファイルのexif情報の差分を表示するには(exifツールがインストールされていると仮定して)、$GIT_DIR/configファイル(または$HOME/.gitconfigファイル)に次のセクションを追加します。

[diff "jpg"]
        textconv = exif

mingw32のソリューションであるcygwinファンは、アプローチを変更する必要があるかもしれません。問題は、ファイル名を渡してcmd.exeに変換することです。これはスラッシュを使用し、cmdはバックスラッシュのディレクトリ区切り文字を想定しています。

ステップ1:

stdoutへの変換を行う単一引数スクリプトを作成します。c:\ path \ to \ some \ script.sh:

#!/bin/bash
SED='s/\//\\\\\\\\/g'
FILE=\`echo $1 | sed -e "$SED"\`
cmd.exe /c "type $FILE"

ステップ2:

スクリプトファイルを使用できるようにgitを設定します。git config(~/.gitconfigまたは.git/configまたはを参照man git-config)内に、次のように配置します。

[diff "cmdtype"]
textconv = c:/path/to/some/script.sh

ステップ3:

.gitattributesファイルを利用してこのworkarondを適用するファイルを指摘します(man gitattributes(5)を参照)。

*vmc diff=cmdtype

次にgit diff、ファイルで使用します。

于 2009-07-09T03:48:46.320 に答える
4

小さなgit-diffドライバーを作成しました。これによりto-utf8、ASCII/UTF-8でエンコードされていないファイルを簡単に比較できるようになります。https://github.com/chaitanyagupta/gitutils#to-utf8の手順を使用してインストールできます(to-utf8スクリプトは同じリポジトリで利用できます)。

このスクリプトでは、fileiconvコマンドの両方がシステムで使用可能である必要があることに注意してください。

于 2013-04-02T08:37:01.467 に答える
3

最近Windowsでこの問題が発生し、Windows用のgitに付属しているとbinがうまくいきましたdos2unixunix2dosデフォルトでは、これらはにありますC:\Program Files\Git\usr\bin\これは、ファイルがUTF-16である必要がない場合にのみ機能することに注意してください。たとえば、Pythonファイルを必要のないときに誤ってUTF-16としてエンコードした人がいます(私の場合)。

PS C:\Users\xxx> dos2unix my_file.py
dos2unix: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 Unix format...

PS C:\Users\xxx> unix2dos my_file.py
unix2dos: converting UTF-16LE file my_file.py to ANSI_X3.4-1968 DOS format...
于 2018-07-24T15:46:20.727 に答える
1

他の回答で説明されているように、git diffはUTF-16ファイルをテキストとして処理しないため、たとえばAtlassianSourceTreeでは表示できなくなります。ファイル名またはサフィックスがわかっている場合は、以下の修正により、これらのファイルがSourceTreeで通常表示および比較できるようになります。

UTF-16ファイルのファイルサフィックスがわかっている場合(たとえば、*。uni)、そのサフィックスを持つすべてのファイルを、次の2つの変更を加えてUTF-16からUTF-8へのコンバーターに関連付けることができます。

  1. 次の行を使用して、リポジトリのルートディレクトリに.gitattributesファイルを作成または変更します。

     *.uni diff=utf16
    
  2. 次に、ユーザーのホームディレクトリ(C:\ Users \ yourusername \ .gitconfig)の.gitconfigファイルを次のセクションで変更します。

    [diff=utf16]
        textconv = "iconv -f utf-16 -t utf-8"
    

これらの2つの変更は、リポジトリをSourceTreeにリロードせずにすぐに有効になります。すべての*.uniファイルにテキスト変換を適用し、他のテキストファイルと同様に表示および比較できるようにします。他のファイルでこの変換が必要な場合は、.gitattributesファイルに行を追加できます。(指定されたファイルがUTF-16でない場合、そのファイルの結果は読み取れません。)

この回答は、TonyKuneckの回答を簡略化して書き直したものであることに注意してください。

于 2021-03-29T14:51:59.527 に答える