5

プロジェクトのファイルのパーミッションを変更した後、同僚が git commit を行いました (彼はファイルがコミットされるとは思っていませんでした)。

これで、すべての画像が「破損」して読み取り不能になりましたが、どのように、何をすべきかわかりません。

git show edd703783a8802284fb975e9f354394541f1bad5表示される内容は次のとおりです。

diff --git a/public/bootstrap/img/glyphicons-halflings-white.png b/public/bootstrap/img/glyphicons-halflings-white.png
index 3bf6484..c016d6b 100644
Binary files a/public/bootstrap/img/glyphicons-halflings-white.png and b/public/bootstrap/img/glyphicons-halflings-white.png differ

どういう意味ですか?

イメージを削除して再コミットしようとしましたが、問題は残ります。ブランチで切り替え/再切り替えするとすぐに、イメージが破損します。

私もgit revertコミットしようとしましたが、すべての画像ファイルが更新された状態になり、次のエラーで停止します。

error: 'commit' is not possible because you have unmerged files.
hint: Fix them up in the work tree,
hint: and then use 'git add/rm <file>' as
hint: appropriate to mark resolution and make a commit,
hint: or use 'git commit -a'.
fatal: Exiting because of an unresolved conflict.

今は元に戻すことができず、コミットは数日前にプッシュされた (そして開発環境にデプロイされた) ため、リベースなどはできません。

4

1 に答える 1

7
diff --git a/public/bootstrap/img/glyphicons-halflings-white.png b/public/bootstrap/img/glyphicons-halflings-white.png
index 3bf6484..c016d6b 100644
Binary files a/public/bootstrap/img/glyphicons-halflings-white.png and b/public/bootstrap/img/glyphicons-halflings-white.png differ

これは単にglyphicons-halflings-white.pngそのコミットで が変更されたことを意味しますが、内容はバイナリであり、端末での表示には適していません。その結果、端末の破損を避けるために実際の diff は省略されます (端末はいくつかのコードを解釈するため、生データを端末にストリーミングしたくありません)。

次のビットはもっと興味深いです:

error: 'commit' is not possible because you have unmerged files.
hint: Fix them up in the work tree,
hint: and then use 'git add/rm <file>' as
hint: appropriate to mark resolution and make a commit,
hint: or use 'git commit -a'.
fatal: Exiting because of an unresolved conflict.

これは、マージを試みたときにファイルに競合があったことを意味します。これは、変更の元となったバージョンが、マージ先のブランチの先端にあるバージョンと同じではないために発生します。グラフ的には、このようになります

                       C
         .-------------*------------.
        /                            \
*------*---------------*--------------+
A      B               D              E

したがって、コミット B に基づいてこれらのアイコン (コミット C) を更新するフィーチャー ブランチがあったとします。その後、他の誰かが同じファイルを変更するマスターに変更を加えました。たとえば、コミット D です。マージしようとすると、コミットします。 C と D は、同じバイナリ ファイルに触れているため、競合しています。Git はバイナリ形式を認識しないため、それらをマージする方法がわかりません。ユーザーとして、競合を解決してから、結果を追加してコミットする必要があります。つまり、コミット B に基づくバージョン (マージ ベース)、コミット C に基づくバージョン (MERGE_HEAD/自分のバージョン)、コミット D に基づくバージョン (マスターの HEAD/バージョン) の 3 つのバージョンすべてを調べる必要があります。これを行うと、これらの各バージョンを表示できます。

git show :1:path/to/file.ext > file.merge-base.ext    # The merge base (commit B)
git show :2:path/to/file.ext > file.HEAD.ext          # The version on the branch you're merging into (commit D)
git show :3:path/to/file.ext > file.MERGE_HEAD.ext    # The version on your branch (commit C)

これらの異なるバージョンにアクセスするためのコマンドは、git mergeの man ページに記載されています。ステージング構文の詳細については、gitrevisions man ページのSpecifying Revisionsセクションを参照してください。

そのコミットの前に元のバージョンを復元してみることができます。次のようになります。

git show edd703783a8802284fb975e9f354394541f1bad5~1:public/bootstrap/img/glyphicons-halflings-white.png > public/bootstrap/img/glyphicons-halflings-white.png
git commit -M "Revert the last set of changes made to icons." public/bootstrap/img/glyphicons-halflings-white.png

あなたの木の上から走ったとき。バージョンを保持するように選択することもできます。

git checkout --ours  # Keeps the version on master (commit D, the :2: version)

または、

git checkout --theirs  # Keeps the version from your branch (commit C, the :3: version)

次に、ファイルを追加してコミットし、マージを解決する必要があります。

最後に、ファイルに次のような行がまだない場合は、.gitattributesそれを検討することをお勧めします。

*.png    binary

これは、バイナリ ファイルをバイナリとして扱うことを意味します。Git はファイルの内容をマージしようとしません。通常、git は最初の 100 バイト (IIRC) で NUL 文字を探すことによってバイナリ検出を行います。PNG 形式を覚えていませんが、おそらく最初の 100 バイトに 1 つであることが保証されていない可能性があるため、git はファイルの内容をマージして競合マーカーを挿入しようとする場合があります。それは、画像プログラムやブラウザで見ることができない方法で画像を破損させます。私はそれがあなたに起こったことだと思います. ファイルの上記の行は、.gitattributesgit が競合マーカーを挿入しないようにし、ブランチ間のコミットされていない変更を .png ファイルにマージしようとするのを回避します。

于 2013-07-09T13:18:07.587 に答える