确定二进制文件是否在解析时被更改"两者都添加了" git冲突

时间:2016-10-29 22:26:41

标签: git binaryfiles rebase merge-conflict-resolution

我正在进行一次改变,遇到"两者都添加了"二进制文件的冲突。我想接受我们的'如果二进制文件是相同的,那么他们的文件是'如果他们改变了在解决过程中,如何测试二进制文件是相同还是不同?

1 个答案:

答案 0 :(得分:1)

如果文件匹配,则不会发生冲突。

让我们通过例子来说明这一点。虽然你在讨论rebase(vs merge),但冲突的处理方式相同,因为它涉及相同的代码:

$ mkdir addadd; cd addadd; git init
Initialized empty Git repository in /home/torek/tmp/addadd/.git/
$ echo a repository for testing add/add conflict > README
$ git add README
$ git commit -m initial
[master (root-commit) f665e86] initial
 1 file changed, 1 insertion(+)
 create mode 100644 README

现在我们需要一些二进制文件。我将使用/bin/ls/bin/cat,并将相同的二进制文件放在一个名称下分成两个分支,将一个名称下的不同版本放入另外两个分支中:

$ git checkout -b b1 master
Switched to a new branch 'b1'
$ cp /bin/ls some-file
$ git add some-file && git commit -m 'add some-file on b1'
[b1 5128ae4] add some-file on b1
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100755 some-file
$ git checkout -b b2 master
Switched to a new branch 'b2'
$ cp /bin/ls some-file
$ git add some-file && git commit -m 'add some-file on b2'
[b2 0e7d771] add some-file on b2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100755 some-file

现在我们尝试将b1合并到b2,反之亦然。我们已经在b2,所以让我们在这里合并b1

$ git merge --no-edit b1
Merge made by the 'recursive' strategy.
$ git log --oneline --decorate --graph --all
*   257e77a (HEAD -> b2) Merge branch 'b1' into b2
|\  
| * 5128ae4 (b1) add some-file on b1
* | 0e7d771 add some-file on b2
|/  
* f665e86 (master) initial

现在让我们尝试使用不同的二进制文件:

$ git checkout -b b3 master
Switched to a new branch 'b3'
$ cp /bin/ls some-file
$ git add some-file && git commit -m 'add some-file on b3'
[b3 2ede434] add some-file on b3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100755 some-file
$ git checkout -b b4 master
Switched to a new branch 'b4'
$ cp /bin/cat some-file 
$ git add some-file && git commit -m 'add different some-file on b4'
[b4 9e5f2cf] add different some-file on b4
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100755 some-file

同样,我们会在这里将b3合并到b4

$ git merge --no-edit b3
warning: Cannot merge binary files: some-file (HEAD vs. b3)
Auto-merging some-file
CONFLICT (add/add): Merge conflict in some-file
Automatic merge failed; fix conflicts and then commit the result.
$ git status --short
AA some-file

这次,合并失败并出现添加/添加冲突。这意味着文件不同:先前的合并成功,因为文件是相同的。合并尚未完成,但我们仍然可以查看提交图:

$ git log --oneline --decorate --graph --all
* 9e5f2cf (HEAD -> b4) add different some-file on b4
| * 2ede434 (b3) add some-file on b3
|/  
| *   257e77a (b2) Merge branch 'b1' into b2
| |\  
| | * 5128ae4 (b1) add some-file on b1
| |/  
|/|   
| * 0e7d771 add some-file on b2
|/  
* f665e86 (master) initial

有趣的是,当文件相同时,我们甚至都没有收到警告信息。这是因为当文件匹配时,Git的合并机器会绕过所有常用的合并代码。 1 特别是,.gitattributes文件中的自定义合并驱动程序永远不会运行。

通过运行git ls-files --stage,我们可以看到文件不同(并且存在添加/添加冲突):

$ git ls-files --stage
100644 661d9d91972de27e4f787e3ad93ea3b7a1741ddf 0   README
100755 b75a044e06fb5e093a547c4ef9a388313d27f79a 2   some-file
100755 2ca93e76b4dedc9970cca9a708ab1cb94ca032ee 3   some-file

路径名some-file作为阶段2和3存在,但不作为阶段1(基础)存在。这意味着该文件没有基本版本:所以这是添加/添加冲突。第2阶段的哈希--oursb75a044...,第3阶段或--theirs的哈希为2ca93e7...,我们也可以使用git rev-parse查看:

$ git rev-parse :2:some-file
b75a044e06fb5e093a547c4ef9a388313d27f79a

(如果需要,请重复:3:some-file。)

1 更准确地说,Git只是检查索引条目的散列是否与另一个散列或--theirs提交中的散列相匹配。如果是这样,它根据定义是相同的文件,并且不需要合并操作。