阻止 Git 快进自动合并
Prevent Git Fast Forward Automatic Merge
问题上下文示例:
- 分支 B 是从 A 分支
创建的
- 在分支 B 中创建并编辑了多次名为
XPTO.txt
的文件(多次提交)
- 另一个分支 C 是从分支 B 之后创建的
- 并行
XPTO.txt
在分支 B 和 C[=60= 中再次被编辑多次(多次提交) ]
- 分支 C 必须合并回 A
- 从分支 C 到分支 A 的拉取请求 (PR) 不得包含来自
XPTO.txt
中的更改在创建分支 C 之前分支 B
假设删除 B 分支代码的这些更改(提交)正确完成并且不影响项目构建等
我应该如何正确管理存储库以便:
- 合并分支 B 代码删除提交在分支 A
- 避免(尽可能地)在分支 B 打开 PR 以便合并到分支 A[=60 时发生合并冲突=]
- 最重要的:隐式避免,如果可能,Git可能发生的快进
Scale the example to several files and several changes (commits).
到目前为止我认为唯一的答案是强制从分支 B 进行非 FF 合并到分支 A 但仍然得到Already up to date!
有时。
谢谢。
鉴于这些步骤:
- 分支 B 是从 A 分支
创建的
- 在分支 B 中创建并编辑了多次名为
XPTO.txt
的文件(多次提交)
- 另一个分支 C 是从分支 B 之后创建的
- 并行
XPTO.txt
在分支 B 和 C[=71= 中再次被编辑多次(多次提交) ]
您的存储库看起来像这样:
(B)
|
v
<--b3 <--b4
/
a1 <--a2 <--b1 <--b2
^ \
| <--c1 <--c2
(A) ^
|
(C)
小写标签是单独的提交,link通过它们的“父”引用(向后的箭头)组合在一起。大写标签是分支,在 git 的模型中只是指向特定提交的指针,可用于引用该提交及其所有祖先。
请注意,提交 b1 和 b2 最初是在分支 B 上创建的,但就 git 而言,它们只是分支 C 历史的一部分。
所以现在:
- 从分支 C 到分支 A 的拉取请求 (PR) 不能包含在创建分支 C 之前从分支 B 在 XPTO.txt 中所做的更改
没有直接的方式告诉 git - 它不知道哪些提交“属于”分支 B 或“在”分支 C 之前。如果您要求将分支 C 合并到 A,它会回头直到找到一个共同的祖先,即 a2,因此要合并的提交是 b1、b2、c1 和 c2。
为了“删除”这些提交,您需要创建历史记录中没有它们的新提交。这就是“git rebase”命令的用途。
在这种情况下,您需要将“b2”之后的提交变基到“A”,因此命令为 git rebase b2 C --onto A
。结果将如下所示:
(B)
|
v
<--b3 <--b4
/
a1 <--a2 <--b1 <--b2
^ \ \
| \ <--c1 <--c2
(A) \
<--c3 <--c4
^
|
(C)
现在提交 b1 和 b2 不再是 C 历史的一部分。
提交 c3 和 c4 将分别由基于 c1 和 c2 的 rebase 命令创建,但不要 link 以任何方式对它们进行修改。如果没有其他分支或标记指向提交 c1 和 c2,它们最终将作为孤立数据被“垃圾收集”。
如果您想要 部分 来自提交 b1 和 b2 的更改,您需要将它们作为新提交手动添加回来。这可能会或可能不会导致以后发生冲突,具体取决于合并算法是否可以弄清楚您要做什么。但这只是生活中的一个事实:对同一个文件的两个并行更改存在冲突的风险。
请注意,这与 还原 更改(使用“git 还原”,或手动撤消它们)有很大不同,后者会创建 额外的 历史记录:
(B)
|
v
<--b3 <--b4
/
a1 <--a2 <--b1 <--b2
^ \
| <--c1 <--c2 <--rb1 <--rb2
(A) ^
|
(C)
此处,“rb1”撤消了“b1”的更改,“rb2”撤消了“b2”的更改,但是所有四个提交 都是 C 历史的一部分。一旦你合并到 A,它们也将成为 A 历史的一部分,所以当你合并到分支 B 时,只有 b3 和 b4 是“新的”。
解决此问题的唯一其他方法是重新设置分支 B 以创建提交的新副本以在 恢复后合并。这导致了一段混乱的历史,但有时也是摆脱混乱的出路。
(B)
|
V
<--b5 <--b6 <--b7 <--b8
/
|
| <--b3 <--b4
| /
a1 <--a2 <--b1 <--b2
^ \
| <--c1 <--c2 <--rb1 <--rb2
(A) ^
|
(C)
这里的b5、b6、b7、b8是b1、b2、b3、b4通过rebase命令重新创建的版本。
问题上下文示例:
- 分支 B 是从 A 分支 创建的
- 在分支 B 中创建并编辑了多次名为
XPTO.txt
的文件(多次提交) - 另一个分支 C 是从分支 B 之后创建的
- 并行
XPTO.txt
在分支 B 和 C[=60= 中再次被编辑多次(多次提交) ] - 分支 C 必须合并回 A
- 从分支 C 到分支 A 的拉取请求 (PR) 不得包含来自
XPTO.txt
中的更改在创建分支 C 之前分支 B
假设删除 B 分支代码的这些更改(提交)正确完成并且不影响项目构建等
我应该如何正确管理存储库以便:
- 合并分支 B 代码删除提交在分支 A
- 避免(尽可能地)在分支 B 打开 PR 以便合并到分支 A[=60 时发生合并冲突=]
- 最重要的:隐式避免,如果可能,Git可能发生的快进
Scale the example to several files and several changes (commits).
到目前为止我认为唯一的答案是强制从分支 B 进行非 FF 合并到分支 A 但仍然得到Already up to date!
有时。
谢谢。
鉴于这些步骤:
- 分支 B 是从 A 分支 创建的
- 在分支 B 中创建并编辑了多次名为
XPTO.txt
的文件(多次提交) - 另一个分支 C 是从分支 B 之后创建的
- 并行
XPTO.txt
在分支 B 和 C[=71= 中再次被编辑多次(多次提交) ]
您的存储库看起来像这样:
(B)
|
v
<--b3 <--b4
/
a1 <--a2 <--b1 <--b2
^ \
| <--c1 <--c2
(A) ^
|
(C)
小写标签是单独的提交,link通过它们的“父”引用(向后的箭头)组合在一起。大写标签是分支,在 git 的模型中只是指向特定提交的指针,可用于引用该提交及其所有祖先。
请注意,提交 b1 和 b2 最初是在分支 B 上创建的,但就 git 而言,它们只是分支 C 历史的一部分。
所以现在:
- 从分支 C 到分支 A 的拉取请求 (PR) 不能包含在创建分支 C 之前从分支 B 在 XPTO.txt 中所做的更改
没有直接的方式告诉 git - 它不知道哪些提交“属于”分支 B 或“在”分支 C 之前。如果您要求将分支 C 合并到 A,它会回头直到找到一个共同的祖先,即 a2,因此要合并的提交是 b1、b2、c1 和 c2。
为了“删除”这些提交,您需要创建历史记录中没有它们的新提交。这就是“git rebase”命令的用途。
在这种情况下,您需要将“b2”之后的提交变基到“A”,因此命令为 git rebase b2 C --onto A
。结果将如下所示:
(B)
|
v
<--b3 <--b4
/
a1 <--a2 <--b1 <--b2
^ \ \
| \ <--c1 <--c2
(A) \
<--c3 <--c4
^
|
(C)
现在提交 b1 和 b2 不再是 C 历史的一部分。
提交 c3 和 c4 将分别由基于 c1 和 c2 的 rebase 命令创建,但不要 link 以任何方式对它们进行修改。如果没有其他分支或标记指向提交 c1 和 c2,它们最终将作为孤立数据被“垃圾收集”。
如果您想要 部分 来自提交 b1 和 b2 的更改,您需要将它们作为新提交手动添加回来。这可能会或可能不会导致以后发生冲突,具体取决于合并算法是否可以弄清楚您要做什么。但这只是生活中的一个事实:对同一个文件的两个并行更改存在冲突的风险。
请注意,这与 还原 更改(使用“git 还原”,或手动撤消它们)有很大不同,后者会创建 额外的 历史记录:
(B)
|
v
<--b3 <--b4
/
a1 <--a2 <--b1 <--b2
^ \
| <--c1 <--c2 <--rb1 <--rb2
(A) ^
|
(C)
此处,“rb1”撤消了“b1”的更改,“rb2”撤消了“b2”的更改,但是所有四个提交 都是 C 历史的一部分。一旦你合并到 A,它们也将成为 A 历史的一部分,所以当你合并到分支 B 时,只有 b3 和 b4 是“新的”。
解决此问题的唯一其他方法是重新设置分支 B 以创建提交的新副本以在 恢复后合并。这导致了一段混乱的历史,但有时也是摆脱混乱的出路。
(B)
|
V
<--b5 <--b6 <--b7 <--b8
/
|
| <--b3 <--b4
| /
a1 <--a2 <--b1 <--b2
^ \
| <--c1 <--c2 <--rb1 <--rb2
(A) ^
|
(C)
这里的b5、b6、b7、b8是b1、b2、b3、b4通过rebase命令重新创建的版本。