git存储库中的图像损坏

时间:2013-07-09 09:02:59

标签: git

一位同事在更改项目文件的权限后做了一个git提交(他不希望提交它们)。

现在我们所有的图片都“损坏”不可读,但我们不明白怎么做以及做什么。

以下是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.

现在我无法恢复它,并且提交已经在几天前被推送(并部署到开发环境),所以我不能修改或类似的东西。

1 个答案:

答案 0 :(得分: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,但内容是二进制的,不适合在终端中显示。因此,它省略了任何实际的差异以避免损坏您的终端(终端解释一些代码,因此您不希望将原始数据流式传输到它)。

接下来的一点更有趣:

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 /版本在主服务器上)。您可以通过以下方式查看每个版本:

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手册页中。有关登台语法的更多信息,您可以查看Specifying Revisions section of the gitrevisions手册页。

您可以尝试在提交之前恢复原始版本。它看起来像是:

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个字节中有一个,因此git可能会尝试合并文件的内容并插入冲突标记。这会以图像程序或浏览器无法查看的方式破坏图像,我怀疑这是发生在你身上的事情。 .gitattributes文件中的上一行将确保git不插入冲突标记,并且它将避免尝试将分支之间未提交的更改合并到.png文件。