なぜGitはこのテキストファイルをバイナリファイルとして扱うのですか?


150

なぜgitがこれを教えてくれるのでしょうか?

$ git diff MyFile.txt
diff --git a/MyFile.txt b/MyFile.txt
index d41a4f3..15dcfa2 100644
Binary files a/MyFile.txt and b/MyFile.txt differ

彼らはテキストファイルではありませんか?

.gitattributesを確認しましたが、空です。なぜこのメッセージが表示されるのですか?いつものように差分を取得できません

追加:

@ファイルのアクセス許可があることに気付きましたが、これは何ですか?これが理由でしょうか?

$ls -all
drwxr-xr-x   5 nacho4d  staff    170 28 Jul 17:07 .
drwxr-xr-x  16 nacho4d  staff    544 28 Jul 16:39 ..
-rw-r--r--@  1 nacho4d  staff   6148 28 Jul 16:15 .DS_Store
-rw-r--r--@  1 nacho4d  staff    746 28 Jul 17:07 MyFile.txt
-rw-r--r--   1 nacho4d  staff  22538  5 Apr 16:18 OtherFile.txt

4
UTF-8でエンコードされたファイルである可能性があります。
Marnix van Valen、2011

UTF16リトルエンディアンLFになるはずです
nacho4d

1
lsMac OS Xのマンページから:ファイルまたはディレクトリに拡張属性がある-l場合、オプションによって出力される権限フィールドの後に@文字が続きます。オプション-@を使用して、これらの拡張属性を表示します。
adl 2011

これはgitのバグかもしれません。私は拡張属性を削除しましたが、今やすべてが再び元気になっています。
nacho4d 2011

4
@ nacho4d:拡張属性があることをgitが認識していないため、これは奇妙です。それを再現できれば、gitメーリングリストで取り上げる価値があります。vger.kernel.orgリストの慣習として、投稿を購読する必要はありません(人々は回答のためにCCを取得し続けます)。そして、git@vger.kernel.orgリストのボリュームがかなり大きいことを想定してはいけません。
Jan Hudec、2011

回答:


76

これは単に、gitがファイルの実際のコンテンツを検査するときを意味します(特定の拡張子がバイナリファイルでないことはわかりません。明示的に伝えたい場合は、属性ファイルを使用できます。manページを参照してください)。

ファイルの内容を調べたところ、基本的なASCII文字ではないものを見つけました。UTF16であることから、「おかしい」文字が含まれることが予想されるため、バイナリであると見なされます。

ファイルに国際化(i18n)または拡張文字フォーマットがあるかどうかをgitに伝える方法があります。私はそれを設定するための正確な方法を十分に理解していません-あなたはRT [Full] Mをする必要があるかもしれません;-)

編集:SOのクイック検索でcan-i-make-git-recognize-a-utf-16-file-as-textが見つかり、いくつかの手掛かりが得られるはずです。


10
あなたはほぼ間違いなく、完全に間違っているわけではありません。Gitは実際のファイルを検査し、そこに「おかしい」キャラクターを見ました。ただし、UTF-16はバイナリであると「考える」ことはできません。それはあるテキストは(組み込みの差分だ唯一のことは、のために使用可能な結果を与えること)ASCIIベースとして定義されているため、バイナリおよびUTF-16ではありません。はい、パターン定義ファイルに特別なdiffを使用するようにgitに指示する方法があります(を使用.gitattributes)。
Jan Hudec、2011

2
追加する必要があります、その「面白い文字」は本当にゼロバイトを意味します。
Jan Hudec、2011

4
私たちはどちらも正しいですが、異なる観点からです。どちらも「Gitは内容を検査してタイプを判別する」と言います。我々 gitのは、ユーザーがgitのを経由して通知する必要がありますUTF16として扱われるべきである知っているようにすると言うの両方.gitattributesなどを
フィリップ・オークリー

7
@JanHudec:あなたの見解では、すべてのファイルはバイナリです。
stolsvik 2016年

2
@stolosvik、(およびJanH)UTF-8には、ベース0〜127 ASCII文字と他のすべてのUnicode文字の両方が含まれているため、null文字以外にnull(00h)バイトを必要とせず、より微妙な中間点になっています。 ( 'C'文字列ターミネーター)。したがって、Gitのテキスト定義では、utf-8エンコードの場合、コンテンツ(最初の1kバイト)にnullバイトを含めないようにする必要があります。楽しい読み物として、stackoverflow.com / questions / 2241348 /…を試してください。私の元のコメントは、ASCIIコードポイントの上位バイトが00になるようUTF-16エンコードされたデータは、バイトペアとして見た場合を意味する
フィリップオークリー

41

ファイルのタイプを設定していない場合、Gitはそれを自動的に判別しようとします。実際に長い行と、おそらくいくつかのワイド文字(Unicodeなど)を含むファイルは、バイナリとして扱われます。.gitattributesのファイルあなたはGitがファイルをinterpretes方法を定義することができます。diff属性を手動で設定すると、Gitはファイルの内容をテキストとして解釈し、通常のdiffを実行します。

リポジトリのルートフォルダーに.gitattributesを追加し、diff属性をパスまたはファイルに設定するだけです。次に例を示します。

src/Acme/DemoBundle/Resources/public/js/i18n/* diff
doc/Help/NothingToSay.yml                      diff
*.css                                          diff

ファイルに属性が設定されているかどうかを確認する場合は、git check-attrを使用して行うことができます。

git check-attr --all -- src/my_file.txt

Git属性に関するもう1つの優れたリファレンスは、こちらにあります


1
これは役に立ちましたが、実際には正しくdiffありませんtext。正しい属性は、ではなくです。このtext属性は、テキストを使用して比較するようにgitに指示しませんが、行末の処理方法(LFへの正規化)を制御します。詳細については、.gitattributesへのリンクを参照してください。
ErikE 2014

@ErikEに感謝します。私はあなたのコメントとGitドキュメントに従って私の投稿を更新しました。
naitsirch 2014

4
さらに、実行する差分の種類を設定できます。たとえば、それがxmlファイルの場合diff=xml、単にの代わりに使用できますdiff
Sandy Chapman

1
check-attrの反対は何ですか-set-attrはありますか?最初に誤ってファイルをUTF-16として保存してからコミットしてプッシュしましたが、BitBucketはファイルをUTF-8として再保存して再度コミットしてプッシュした後でも、UTF-16として認識します。レビュー担当者はレビューコメントを追加するために個々のコメントをクリックする必要があるため、これは基本的に私のプルリクエストを読むことを不可能にします。
John Zabroski、2016年

21

私はこの問題を抱えていましたが、Git GUIとSourceTreeはJava / JSファイルをバイナリとして扱っていたため、違いがわかりませんでした。

.git \ infoフォルダに「attributes」という名前のファイルを作成し、次の内容で問題を解決しました

*.java diff
*.js diff
*.pl diff
*.txt diff
*.ts diff
*.html diff

すべてのリポジトリにこの変更を加えたい場合は、$ HOME / .config / git / attributesにある属性ファイルを追加できます。


1
また、<project-root>/.gitattributesファイルに注意してください。これにより、変更がすべての寄稿者に対して、関連プロジェクトに対してのみアクティブになります。
jpaugh

追加* diffは私にとって役に立ちました。それはすべてのタイプのファイルの違いを示しています。ただし、大きなバイナリファイルで不必要なdiffが表示されないようにするため、ソリューションの方が優れています。
Boolean_Type

うん!これは役立ちます!
WildCat

19

テキストファイルに非常に長い行が1つある場合、Gitはそれがバイナリであると判断します。長い文字列を分割し、それをいくつかのソースコード行に変換したところ、突然、ファイルが「バイナリ」から(SmartGitで)見えるテキストファイルになりました。

そのため、エディターで「Enter」を押すことなく、あまりにも右に入力しすぎないでください。そうしないと、後でGitでバイナリファイルが作成されたと見なされます。


1
これは正しい情報です。非常に大きなMySQLダンプ(.sqlファイル)との差分を制御しようとしましたが、ASCII / UTF8データしか含まれていない場合でも、gitはそれをバイナリファイルとして扱います。その理由は、行が非常に長いためです(値を挿入(1)、(2)、(3)、(...)、(3,000,000 ...))。奇妙なことに、すべてのコミットに対して、gitリポジトリは1.7 GBずつ増加するのではなく、約350 MBまでにします。おそらく、gitが「バイナリ」ファイルを保存する前に圧縮しています
Alexandre T.

@AlexandreT。Gitは確かにファイルBLOBを圧縮します(GZip、IIRCを使用)。
jpaugh

11

新しいエディターでファイルの1つを編集した後も、同じ問題が発生しました。新しいエディターは、以前のエディター(UTF-8)とは異なるエンコーディング(Unicode)を使用していることがわかりました。そのため、新しいエディターにファイルをUTF-8で保存するように指示しただけで、gitは変更内容を適切に表示し、バイナリファイルとして表示しませんでした。

問題は単にgitが異なるエンコーディングタイプのファイルを比較する方法を知らないということでした。したがって、一貫性が保たれている限り、使用するエンコーディングタイプは実際には問題になりません。

私はそれをテストしませんでしたが、新しいUnicodeエンコーディングでファイルをコミットしただけなら、次にそのファイルに変更を加えたときに、変更が正しく表示され、バイナリとして検出されなかったでしょう。次に、UTF-8ファイルではなく2つのUnicodeエンコードファイルをUnicodeファイルと比較します。

Notepad ++などのアプリを使用すると、テキストファイルのエンコードタイプを簡単に確認および変更できます。Notepad ++でファイルを開き、ツールバーの[エンコード]メニューを使用します。


1
Unicodeはエンコーディングではありません。これは文字セットであり、UTF-8はそのエンコードの1つです。つまり、Unicodeコードポイントをエンコードする方法です
phuclv

1
これは問題を解決せず、回避するだけです。問題は、gitまたはそのdiffツールがテキストファイルを適切に認識しないか、ユーザーがその動作を簡単に上書きできないことです。
Preza8

6

同じ問題がありました。グーグルで解決策を検索したときにスレッドを見つけましたが、それでも手掛かりは見つかりません。しかし、私は勉強した後で理由を見つけたと思います、以下の例は私の手がかりを明確に説明します。

    echo "new text" > new.txt
    git add new.txt
    git commit -m "dummy"

今のところ、ファイルnew.txtはテキストファイルと見なされます。

    echo -e "newer text\000" > new.txt
    git diff

あなたはこの結果を得るでしょう

diff --git a/new.txt b/new.txt
index fa49b07..410428c 100644
Binary files a/new.txt and b/new.txt differ

そしてこれを試してください

git diff -a

あなたは以下になります

    diff --git a/new.txt b/new.txt
    index fa49b07..9664e3f 100644
    --- a/new.txt
    +++ b/new.txt
    @@ -1 +1 @@
    -new file
    +newer text^@

5

このケースでは、.htmlファイルを変更しようとすると、バイナリとして表示されていました。差分を見ないのはとてもクールです。正直に言うと、ここではすべての解決策を確認しませんでしたが、私たちにとってうまくいったのは次のとおりです。

  1. ファイルを削除し(実際にはデスクトップに移動しました)、をコミットしましたgit deletion。GitさんのコメントDeleted file with mode 100644 (Regular) Binary file differs
  2. ファイルを再度追加しました(実際にデスクトップからプロジェクトに戻しました)。GitによるとNew file with mode 100644 (Regular) 1 chunk, 135 insertions, 0 deletions、ファイルは通常のテキストファイルとして追加されます

これ以降、ファイルに加えた変更はすべて、通常のテキスト差分として表示されます。これらのコミットを押しつぶすこともできます(1、2、および3は実際に行った変更です)が、私が将来何をしたかを確認できるようにしたいと思っています。Squashing 1&2はバイナリの変化を示します。


VSからプッシュされた1つまたは2つの(正常にコンパイルされた)cppファイルと同様です。滑稽な比較のためのGithub GUIをレンダリングします。そのようなディンドンインターチェンジでベルを飛ばしたくはありません。一方の側でVSがGithubであると言い、もう一方の側でGithubがVSであると言います。:(
Laurie Stearn

4

パーこの便利な答え、あなたはそれが特定の方法でファイルを扱う直接、なぜGitリポジトリを尋ねることができます。

cd directory/of/interest
file *

次のような有用な出力が生成されます。

$ file *
CR6Series_stats resaved.dat: ASCII text, with very long lines, with CRLF line terminators
CR6Series_stats utf8.dat:    UTF-8 Unicode (with BOM) text, with very long lines, with CRLF line terminators
CR6Series_stats.dat:         ASCII text, with very long lines, with CRLF line terminators
readme.md:                   ASCII text, with CRLF line terminators

6
filegitコマンドではありません。これは、Windowsのgitにパッケージ化された完全に別のツールです。これがgitがバイナリファイルの検出に使用するものであることを示すドキュメントはありますか?
最大

4

これは(少なくともWindowsでは)BOMエンコーディングのUTF-8を持つテキストファイルによっても発生します。エンコーディングを通常のUTF-8に変更すると、Gitはファイルをtype = textとして認識します


1

目的によって.gitignore二重\r(キャリッジリターン)シーケンスを含むインスタンスがありました。

そのファイルはgitによってバイナリとして識別されました。.gitattributesファイルの追加が役立ちました。

# .gitattributes file
.gitignore diff

1
働いた。一部のOSの「アイコン」\ r \ rファイルを無視するための二重の\ rもありました。原因と修正を知っておくと便利です。
hsandt 2018

1

場合はgit check-attr --all -- src/my_file.txt、ファイルをバイナリとしてフラグ付けされていることを示し、そしてあなたがバイナリとしてそれを設定していない.gitattributes、でそれを確認してください/.git/info/attributes


0

Aux.jsをSig.jsなどの別の名前に変更します。

ソースツリーはまだそれをバイナリファイルとして表示していますが、ステージング(追加)してコミットすることができます。


0

目に見えない文字が挿入されてgitにファイルがバイナリであると思わせるバイナリKafkaメッセージからテキストを貼り付けたときに、同様の問題が発生しました。

regexを使用してファイルを検索し、問題のある文字を見つけました[^ -~\n\r\t]+

  • [ このセットの文字に一致
  • ^ このセットにない文字に一致
  • -~ ''(スペース)から '〜'までのすべての文字に一致します
  • \n 改行
  • \r キャリッジリターン
  • \t タブ
  • ] 近いセット
  • + これらの文字の1つ以上に一致する

-2

私は数時間かけてこのリストのすべてを調べ、ソリューションのテストプロジェクトの1つがエクスプローラーにテストを追加しなかった理由を解明しようとしました。

私の場合、VSがプロジェクトへの参照を完全に失っていたことが(おそらく、どこかでgitマージが不十分なために)判明しました。それはまだ構築されていましたが、依存関係を構築するだけであることに気付きました。

その後、依存関係リスト自体に表示されていないことに気づいたので、テストプロジェクト削除して再度追加し、すべてのテストが最終的に表示されました。


2
Visual Studioは実際にはここでは関係ありません。
jpaugh
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.