简体   繁体   English

为什么 git 在挑选樱桃时会发生冲突?

[英]why does git conflict occur during cherry-pick?

I've been using git for quite a while but I never really understood why merge conflicts happen.我使用 git 已经有一段时间了,但我从来没有真正理解为什么会发生合并冲突。 I learnt to resolve them quickly but I feel like not understanding why they happen makes me unhappy.我学会了快速解决它们,但我觉得不理解它们为什么会发生让我不开心。 The most common explanation is the same code region was changed by 2 different commits and now git cannot decide which one to pick makes sense only for the simplest cases.最常见的解释是the same code region was changed by 2 different commits and now git cannot decide which one to pick仅对最简单的情况有意义。

In order to understand better what's going on I created a simple file with 2 lines:为了更好地理解发生了什么,我创建了一个包含 2 行的简单文件:

a
b

and commited it (log message init, branch master).并提交它(日志消息初始化,分支主)。

Then I created a feat branch from master and added a 3rd line: c然后我从master创建了一个feat分支并添加了第三行: c

Then I created another feat2 branch from master and changed b to bb .然后我从master创建了另一个feat2分支并将b更改为bb

Finally, I changed the first line in master to ax .最后,我将master中的第一行更改为ax

The resulting tree looks like this:生成的树如下所示:

$ git tree
* f4c4a9d (feat) add 3rd line: c
| * f050bf8 (feat2) changed 2nd line: b -> bb
|/  
| * 244ed21 (HEAD -> master) change 1st line: a -> ax
|/  
* 51fca0f init

If I want to cherry-pick or merge feat into master it works fine but if I want to cherry-pick feat2 which changes the 2nd line it fails and can't figure out why that happens.如果我想挑选或合并feat到大师,它工作正常,但如果我想挑选改变第二行的feat2 ,它会失败并且无法弄清楚为什么会发生这种情况。

In order for git to be able to apply a change, git needs to be able to get common boundaries between the sections that are being affected.为了让 git 能够应用更改,git 需要能够获得受影响部分之间的共同边界 If no common lines exist in the merge process (keep in mind that a cherry-pick is like a normal merge, the only trick is that what is taken as what is the common ancestor in a normal merge, in a cherry-pick it is forced to be the parent of the revision you are cherry-picking), then git will just show you a conflict block.如果合并过程中不存在公共线(请记住,cherry-pick 就像普通合并,唯一的技巧是在普通合并中被视为共同祖先,在cherry-pick 中它是被迫成为您正在挑选的修订版的级),那么 git 只会向您显示一个冲突块。

Keep in mind that you are considering not 2 versions of the file, but three .请记住,您考虑的不是文件的 2 个版本,而是三个.

One version is the common ancestor (in your case, it really is the common ancestor, but in a cherry-pick that is normally not the case):一个版本是共同祖先(在您的情况下,它确实是共同祖先,但在通常情况下并非如此):

a
b

The tip of master:大师的提示:

ax
b

feat2:壮举2:

a
bb

If you consider what remains without change between the 3 versions, nothing survived.... so not much that git can do to figure out what should happen.如果您考虑在 3 个版本之间没有变化的情况,那么没有任何东西可以幸存下来...... git 无法弄清楚应该发生什么。 You get a conflict.你会发生冲突。 If there had been a single unchanged line between the a and b, there would be no problem.如果 a 和 b 之间只有一条不变的线,就没有问题。 Try the same changes on a and b but starting from this file on the first revision:在 a 和 b 上尝试相同的更改,但从第一个修订版的此文件开始:

a
x
b

Then git will have no problem cherry-picking.那么git采樱桃就没有问题了。 It might make more sense if you tried merging using merge.conflictStyle set to diff3 so that you can see how code is in the 3 versions involved.如果您尝试使用设置为diff3merge.conflictStyle进行合并,这可能更有意义,这样您就可以看到代码在所涉及的 3 个版本中的情况。

Side note: if you don't mind sitting down to read, you might want to take a look at something that i am writing on the subject (no monetizing, no tracking): http://www.ezconflict.com旁注:如果您不介意坐下来阅读,您可能想看看我在这个主题上写的东西(没有货币化,没有跟踪): http://www.ezconflict.com

The most common explanation is the same code region was changed by 2 different commits and now git cannot decide which one to pick makes sense only for the simplest cases.最常见的解释是相同的代码区域被 2 个不同的提交更改,现在 git 无法决定选择哪个仅对最简单的情况有意义。

Well, no... that is the explanation, and it applies to all cases.嗯,不……这就是解释,它适用于所有情况。 The detail you may be missing is, if there isn't at least one unchagned line between the lines affected by "our" changes and the lines affected by "their" changes, then the changes are considered overlapping.您可能遗漏的细节是,如果受“我们的”更改影响的行和受“他们的”更改影响的行之间没有至少一条不受影响的行,则这些更改被认为是重叠的。

So in your example:所以在你的例子中:

In master you changed line one.master你改变了第一行。

In one of the branches you added line 3;在其中一个分支中添加了第 3 行; since line 2 is between them, this is not a conflict.由于第 2 行在它们之间,因此这不是冲突。

But in the other branch you changed line 2. There is no line between lines 1 and 2, so this would conflict with the change on master;但是在另一个分支中,您更改了第 2 行。第 1 行和第 2 行之间没有行,所以这会与 master 上的更改冲突; and additionally it would conflict with the addition of line 3 in the other branch (since there are no lines between line 2 and line 3).此外,它会与在另一个分支中添加第 3 行冲突(因为第 2 行和第 3 行之间没有行)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM