在 Git 中标记为已修改的二进制文件的默认版本是什么?

What's the default version of a binary marked as both modified in Git?

如果冲突发生在二进制文件或任何使用文本编辑器无法解决的非文本文件上,我应该改用git checkout --theirsgit checkout --ours,然后将它们添加到暂存区。

但是,如果我什么都不做,直接将那些未合并的二进制文件添加到暂存区,不解决冲突,不选择合适的版本,哪个版本将被添加到暂存区?我们的还是他们的?

Unmerged paths:
  (use "git add/rm <file>..." as appropriate to mark resolution)

      both modified: test.bin
      both modified: test.a 

有时候签入二进制文件是合适的,图片、视频、办公文档...但它们不能合并。你必须选择一个或另一个或制作一个新版本。

但这些看起来像是构建工件;作为构建过程的一部分生成的文件。那些不应该签入。它们将与它们的源代码一起过时,并且它们在具有不同编译器和不同库的不同人的机器上会有所不同。

使用 git rm 删除它们,然后 add them to the project's .gitignore so they don't come back. You'll probably want to ignore entire classes of files like *.a and *.o and *.bin. gitignore.io 可以为您的项目生成一个良好的起始忽略文件。

If the conflict happen on a binary or any non-text files that can't be resolved by using text editor, I should use git checkout --theirs or git checkout --ours instead ...

这不一定是真的。就像纯文本文件一样,有时正确的分辨率实际上是 combined 更改,某些二进制文件的正确分辨率可能是 combined改变。只是 Git 不能为你做这件事。正确执行此操作的唯一方法可能是找到一个或多个源文件,以及某种源代码到二进制的转换器。您可能需要合并源更改,将结果编译/翻译为新的 third 二进制文件,然后使用它。

尽管如此,这个问题还是有答案的。只是学习和记忆它可能没有意义。

But, if I just do nothing, add those unmerged binaries into staging area directly ...

git add 所做的是将工作树中的任何内容复制到槽零处的索引/暂存区域,删除任何更高阶段的条目。在冲突期间,您拥有三个不同的二进制文件,在索引/暂存区中,但使用插槽 1(合并基础)、2(我们的)和 3(他们的)。

因此,这只是意味着将工作树文件复制到插槽 0 中,并删除插槽 1、2 和 3 中的条目。所以问题与以下内容相同:

如果二进制文件发生冲突,Git 会在工作树中留下什么?

两者都有答案 the git merge documentation and the gitattributes documentation。这使阅读变得困难。

第一个说,关于 recursiveresolve 策略,有 其他 参数影响结果。这些附加参数是 -X ours-X theirs 参数,这意味着:

ours
This option forces conflicting hunks to be auto-resolved cleanly by favoring our version. Changes from the other tree that do not conflict with our side are reflected to the merge result. For a binary file, the entire contents are taken from our side.
...
theirs
This is the opposite of ours; note that, unlike ours, there is no theirs merge strategy to confuse this merge option with.

gitattributes 文档添加了这个:

Performing a three-way merge
...
The attribute merge affects how three versions of a file are merged when a file-level merge is necessary ...

然后继续说他们中的大多数人“[k]保留工作树中分支的版本”。所以 通常 工作树匹配 index-slot-2,您可以通过执行 git checkout-index --temp --stage=2 test.bin 并将结果文件与 test.bin.[=32 进行比较来测试=]

尚不清楚此类属性是否覆盖 -X theirs;如果您设置自己的 merge 属性并使用 -X theirs,您将必须对此进行测试,方法是将工作树中的内容与索引槽 2 和 3 中的内容进行比较。

不过,一般来说,大多数方法大多将 "ours" 版本留在工作树中。如果合适,您可以使用 git add 将工作树版本复制回槽 0 并擦除槽 1-3,将文件标记为已解决。只要确保如果您使用了 -X theirs and/or 某种有趣的 merge 设置,您就知道自己在做什么,并且仔细检查了所有内容。

(当然,最好的办法是避免以这种方式合并二进制文件。)