这是怎么一个冲突

时间:2009-11-18 10:31:09

标签: git merge conflict

我只是测试git,看看我是否可以将它用于我的工作。我遇到了一个似乎很小的问题,但可能会成为真正的代码。 我的文件看起来像: 的text.txt     1     2     3     4 我有一个本地分支“branch1”并且在分支和主服务器中都提交了更改。 在主人我改变了第二行的第一行。 因此,大师的差异看起来像这样:

+1 master
 2
 3
 4

分支是:

 1
-2
+2b1
 3
 4

运行git merge branch1解决冲突:

<<<<<<< HEAD
1 master
2
=======
1
2b1
>>>>>>> branch1
3
4

我知道这个可以轻松解决。但无论如何,这又是一场冲突。不应该git能合并吗?

2 个答案:

答案 0 :(得分:5)

几点意见:

  • 首先,这样一个小例子永远不会合并:

    warning: Cannot merge binary files: afile.txt (HEAD vs. abranch)
  • 然后,如果您有许多“小”合并冲突,您知道这些冲突应该独立于上下文来解决,您可以尝试首先在master之上重新定位您的分支,忽略上下文:

    git rebase -C0 master

然后将您的分支合并到master

通常忽略rebase的所有上下文并不是一个好主意,但如果您某些关于您的修改(如“根本不需要上下文的修改”) “),它会起作用。

来自git rebase man page

-C<n>
  

确保每次更改前后至少有<n>条周围环境匹配   当存在较少的周围环境线时,它们都必须匹配   默认情况下,不会忽略任何上下文。


你可以很容易地测试它(在PowerShell会话中,使用Git1.6.5.1,在Xp上)

首先创建一个小型实用程序genfile.bat

echo hello, World %1 > afile.txt
echo hello, World %2 >> afile.txt
echo hello, World 3 >> afile.txt
echo hello, World 4 >> afile.txt
echo hello, World 5 >> afile.txt

然后创建一个repo并添加一个文件:

PS D:\git\tests\mergeLines> git init m0
PS D:\git\tests\mergeLines> cd m0
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1 2
PS D:\[...]\m0> git add -A
PS D:\[...]\m0> git ci -m "afile to be modified concurrently"

您的文件如下所示:

hello, World 1
hello, World 2
hello, World 3
hello, World 4
hello, World 5

在分支

中修改它
PS D:\[...]\m0> git co -b abranch
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1 2_modified
PS D:\[...]\m0> git ci -a -m "afile modified in abranch"

你将拥有:

hello, World 1
hello, World 2_modified
hello, World 3
hello, World 4
hello, World 5

然后在主

中修改它
PS D:\[...]\m0> git co master
PS D:\[...]\m0> D:\git\tests\mergeLines\genfile.bat 1_master 2
PS D:\[...]\m0> git ci -a -m "afile modified in master"

这给了你:

hello, World 1_master
hello, World 2
hello, World 3
hello, World 4
hello, World 5

克隆第一个实验的回购(即:abranch合并到master

PS D:\[...]\m0> cd ..
PS D:\git\tests\mergeLines> git clone m0 m1
PS D:\git\tests\mergeLines> cd m1
PS D:\[...]\m1> git co -b abranch origin/abranch
PS D:\[...]\m1> git co master
PS D:\[...]\m1> git merge abranch

这会给你一个冲突:

Auto-merging afile.txt
CONFLICT (content): Merge conflict in afile.txt
Automatic merge failed; fix conflicts and then commit the result.

PS D:\[...]\m1> type afile.txt
<<<<<<< HEAD
hello, World 1_master 
hello, World 2 
=======
hello, World 1 
hello, World 2_modified 
>>>>>>> abranch
hello, World 3 
hello, World 4 
hello, World 5 

再次克隆第一个回购,这次要在abranch之上首先修改master,没有上下文:

PS D:\[...]\m1> cd ..
PS D:\git\tests\mergeLines> git clone m0 m2
PS D:\git\tests\mergeLines> cd m2
PS D:\[...]\m2> git co -b abranch origin/abranch
PS D:\[...]\m2> git rebase -C0 master

您的文件以静默方式合并:

hello, World 1_master
hello, World 2_modified
hello, World 3
hello, World 4
hello, World 5

当然,如果您切换回master现在合并abranch,结果将是快进合并。

PS D:\git\tests\mergeLines\m2> git co master
Switched to branch 'master'
PS D:\git\tests\mergeLines\m2> git merge abranch
Updating c8f48b4..8bee1d2
Fast forward
 afile.txt |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

答案 1 :(得分:4)

没有上下文可以隔离这两个更改,因此不清楚正确的解决方案应该是什么。使用一行上下文更改为:将块“1/2”更改为“1 master / 2”并将块“1/2/3”更改为“1 / 2b1 / 3”。

尝试将第二个“补丁”应用于第一个补丁的结果会导致错误,因为成功应用补丁所需的上下文不匹配。补丁需要“1/2/3”,但有“1 master / 2/3”。

在更复杂的场景中,充足的上下文非常重要,因为没有它,如果本地分支移动了足够的线并且在原始位置检查了最小量的上下文,则合并很容易在错误的位置应用补丁而不发出警告位置是非常不具体的,补丁仍然应用时不应该。