第二次尝试从分支合并到主分支时发生Git冲突
考虑到以下git网络和流量:第二次尝试从分支合并到主分支时发生Git冲突,git,merge,git-merge,git-merge-conflict,Git,Merge,Git Merge,Git Merge Conflict,考虑到以下git网络和流量: feature-foo _._._2_._._ / \ master __1__/__._.3____._._\___4__5_________7_ (now: 1.1.0-SNAPSHOT) \ release-1.0.x \___.__._._.__6__._._.____ (now: 1.0
feature-foo _._._2_._._
/ \
master __1__/__._.3____._._\___4__5_________7_ (now: 1.1.0-SNAPSHOT)
\
release-1.0.x \___.__._._.__6__._._.____ (now: 1.0.1-SNAPSHOT)
多次执行以下操作:
master
的版本升级到1.0.0-SNAPSHOT
featurefoo
分支中的A.java
release-1.0.x
,将master
的版本升级到1.1.0-SNAPSHOT
,以进行下一个版本的开发B.java
修改为B'.java
仅在master
release-1.0.x
返回到master
(git merge
不通过GitLab MR)release-1.0.x
的版本升级到1.0.0
,并对其进行标记,然后再次升级到1.0.1-SNAPSHOT
release-1.0.x
合并回master
失败,且版本分支最近发生了更改
和3
是通过6
上的bash脚本完成的,带有完整的/tmp
git克隆
和5
在单独的7
上使用完整的/path/to/tmp
git克隆
已合并回主控(接受MR)功能foo
atmaster
had1
A.java
仍然有release-1.0.x
(这很好)A.java
仍然有release-1.0.x
(这很好)B.java
- 一些文件被合并回
,不包括5
和A.java
B.java
5
和7
我都做了
git clone ...
git checkout release-1.0.x
git checkout master
git merge --no-ff --no-commit release-1.0.x
successfully on 5:
git add .
git commit
git push
奇怪的是,在第二次尝试中,我遇到了大量的冲突,包括A.java(它试图将其交给master)和B.java
(它试图将过时的from release分支合并到master并产生冲突)
我的问题是:
- 我是不是遗漏了什么(明显的)
- 将long live release分支合并回master的过程是否正确(例如,每月两次)
- 为什么我现在有冲突而不是第一次尝试
版本在添加到
.gittributes
中的pom.xml
s中进行碰撞,以使用我们的策略进行处理。6之后,master和release都对其版本进行碰撞。您并没有提到碰撞版本的确切含义,但我假设相同文件中的相同行已被编辑到两个分支中,这将导致冲突。至于为什么a.java和b.java突然发生冲突,我的猜测是它们(或它们的路径)是在6期间编辑的。这确实应该是一个注释,但我没有足够的空间放在一个文件中,也无法很好地格式化内容
对于标记为7
的两个提交,您绘制的提交图只有一个合并基,可能根本没有标记(发布版-1.0.x的提示提交)。合并基提交是您标记为3
的提交。但在你的文本中,你说:
一些文件被合并回5
然而,在任何地方都没有连接5
的额外图形线:5
看起来像是一个普通的非合并提交,其(单个)父级是commit4
。因此,我不确定您是否过度简化了图形
最简单的方法是让Git在合并出现问题时告诉您Git认为合并基础是什么。如果您当前在branchmaster
上,并且即将运行git merge release-1.0.x
,您可以使用以下命令查看git认为哪些提交是合并基础(可能是复数):
输出是一些幸运的提交散列ID,只有一个ID是合并的基础。(如果您已经进行了合并,则如果提交是合并前的当前提交,则将HEAD
替换为哈希ID。同样,如果版本-1.0.x自合并后已移动,则将其替换为合并中提交的哈希ID。)
如果有多个合并基,则会有一点问题。Git的默认值是使用-s递归的
合并策略合并合并基。此合并的结果是一个新的“虚拟提交”,然后将其作为最终合并的合并基础。虽然您可以(递归地)手动执行我将要描述的操作,但它会变得非常痛苦:除其他外,您可能必须为每个潜在的虚拟提交进行真正的提交。但是对于任何luck1,都只有一个合并基,可能它毕竟是提交3
无论如何:
我遇到了大量的冲突,包括A.java
和B.java
要查看合并将做什么,以及为什么它认为这两个文件需要合并,请运行:
git diff -M <merge-base-commit> <tip-1> > /tmp/merge-input-1
git diff -M <merge-base-commit> <tip-2> > /tmp/merge-input-2
在差异2中,我们看到:
-another
+another
这些需要组合,所以Git将调用您的合并驱动程序。(更准确地说,Git检查三个散列ID:基本文件的散列、tip#1中文件的散列和tip#2中文件的散列。如果这三个ID不同,Git将调用合并驱动程序。)
另一方面,可能只有tip#1或只有tip#2会更改文件(因此它在基础中与在另一个tip中相同)。在这种情况下,Git会在不运行驱动程序的情况下获取任何一个已更改的文件。对于像pom.xml
这样的文件,这通常是您想要的!(对于版本编号,这可能不是您想要的,但可能您还有另一个步骤来处理。)
如果Git确实调用了您的驱动程序,那么这当然取决于您的驱动程序。这就是“保留我们的”和“git合并文件——我们的”的不同之处。前者更像是-s ours
策略:它完全忽略基本文件和其他/他们的文件。后者使用“两种改变都接受,但如果发生冲突,支持我们”的解决方法,并且是
-this
+that
-another
+another