假设我已经从“A”的旧标签创建了一个分支“B”。我对“B”进行了一些更改,并打开了一个针对“A”的拉取请求。然后我从“B”创建一个“C”分支,我对其进行更改并打开拉取请求等,直到我到达分支“E”。
一旦我完成对“E”的更改,让我们说所有这些分支仍然有针对“A”的开放,未合并的拉取请求。由于这些可以按任何顺序合并,而“E”可能对我在“B”中的原始更改做了一些重要更改,我如何确保“B”具有“C,D,E”的更改; “C”的变化来自“D,E”;而“D”的变化来自“E”。
假设我需要在合并任何拉取请求之前返回并更改A,但它依赖于E的某些更改。
A -----
\
B -----
\
C -----
\
D -----
\
E -----
答案 0 :(得分:1)
您绘制它的方式,C
包含所有B
加上一些,D
包含所有C
加上一些E
全部D
E
1}}加上一些,所以当您将A
合并到D
时,您将C
,B
和A
全部合并到A
,所以B
将拥有一切。
如果您说您可以按任何顺序合并C
,D
,E
或B
中的任何一个,并询问“Git将如何知道要合并的提交内容每一次”?好吧,这是git merge的重要思想之一 - git将返回并意识到已经合并的内容并且不会尝试重新合并这些更改。例如,如果您合并B1
,其由B2
,B3
和C
组成,然后合并C1
(由{{1}组成}},C2
,C3
+ B
(B1
,B2
,B3
)),然后git查看合并历史记录并查找从合并点到达的所有提交,找到未到达的提交并合并那些无法访问的提交 - 这就是它知道要合并的方式(在这种情况下,它将是C1
,{{ 1}},C2
因为它发现C3
,B1
,B2
可以访问)。因此,在内部,例如,如果您已将B3
合并到B
然后告诉它将A
合并到C
,那么git会通过执行来识别未合并的提交像A
之类的东西并合并那些提交。理解这一点的关键是把它想象成一个图并意识到git只是试图弄清楚图表的哪些部分无法从合并点和分支处到达要合并,那些是它想要合并的变化。
如果您在合并git rev-list C --not A
后继续使用B
(B4
),那很好,您只需重新合并分支B
即可。从B
到B
的新更改,因为它执行了我刚才描述的图表遍历,并意识到A
,B1
和B2
已经合并,现在它只是需要合并的新B3
。
答案 1 :(得分:1)
从父分支创建的分支的典型生命周期是前者最终在某个时刻合并回父级。这个概念不仅限于Git,而是一般的开发工作流程。
在您的情况下,如果您遵循此原则,它会立即解决您的问题。这是你的图表,重新绘制得更加可口:
A -----
\
B -----
\
C -----
\
D -----
\
E -----
遵循将分支合并回其父级的原则,合并的顺序应为E
到D
,D
到C
,C
进入B
,最后B
进入A
。在每个合并中,理想情况下应该没有冲突。如果是冲突,则它们不应该归因于父和分支踩到彼此的脚趾,即两个分支都在功能的相同确切区域上工作。
如果您的开发过程可能需要在卷起所有分支之前将E
的更改引入A
,那么您应该重新考虑如何你创建分支。在这种情况下,您最好直接从父分支创建分支A
到E
。