5

一位同事在更改项目文件的权限后进行了 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.

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

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在该提交中已更改,但内容是二进制的,不适合在终端中显示。结果,它省略了任何实际的差异以避免损坏您的终端(终端解释一些代码,因此您不想将原始数据流式传输到它)。

下一点更有趣:

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)的功能分支。然后其他人在 master 上进行了更改,更改了同一个文件,例如提交 D。现在,当您尝试合并时,提交C 和 D 是冲突的,因为它们接触了同一个二进制文件。Git 不理解二进制格式,因此不知道如何将它们合并在一起。作为用户,您需要解决冲突,然后添加并提交结果。这意味着您需要检查所有三个版本:一个基于提交 B(合并基础),一个基于提交 C(MERGE_HEAD/您的版本),一个基于提交 D(HEAD/master 上的版本)。您可以通过执行以下操作查看每个版本:

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手册页中。有关暂存语法的更多信息,您可以查看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 文件。

于 2013-07-09T13:18:07.587 回答