所以问题是这样的: 假设我有一个主节点,我开始从该状态开发到分支A,但随后我创建了一个从分支A 到主节点的 PR,然后我开始在分支 A 之上开发一些东西,因为我需要从该分支A进行一些更改,所以我创建了分支 B。
a -- b -- c ---- h <-- Master
d -- e <-- Branch A
f -- g <-- Branch B
这是我当前的状态,然后由于某种原因,我必须在分支 A 中进行一个小的更改,所以我继续创建一些提交,最后将分支 A 合并到 Master 中。 到那时,我需要变基分支 B 才能从分支 A 获取最新的提交。我该怎么办,这就是我的想象。
a -- b -- c --- -- h <-- Master
/
d -- e -- i <-- Branch A
f -- g <-- Branch B
当你将提交i
添加到你的Branch-A
时,你最终会得到:
a -- b -- c ------ h <-- Master
d -- e -- i <-- Branch-A
f -- g <-- Branch-B
(请记住,您的原始图形包含提交h
因此在合并发生之前必须存在。 进行实际合并会产生一个新的提交j
:
a -- b -- c ------ h -- j <-- Master
/
d -- e -- i <-- Branch-A
f -- g <-- Branch-B
这种合并是必需的,因为必须保留现有的提交h
,而新的提交d-e-i
可以从master
的尖端访问:这需要一个合并提交j
,其父级是两个现有的提交h
和i
。 (如果h
不存在,则可以进行快进操作:这会改变生成的图形形状,因此其效果会波及此答案的其余部分。 让我们假设h
确实存在,并且/或您无论如何都会强制进行非快进合并。
此时,您现在可以选择完全删除名称Branch-A
(随时(,还可以选择将现有提交f
和g
复制到新的和改进的提交f'
和g'
。 这就是你要问的变基。
你应该变基吗? 这是一个更难的问题。 但是,如果其他人都同意原始提交f
并且可以放弃g
,转而使用新的和改进的f'
和g'
,这很好。 它也可能使以后的事情变得更漂亮。 如果您决定不重新调整它们,那么如何做到这一点的问题就没有意义了。
如果您决定变基它们,您的下一个问题需要是:在哪个目标提交?f'
应该在i
之后,还是应该在j
之后? 让我们绘制两个场景:
(option 1: after i)
a -- b -- c ------ h -- j <-- Master
/
d -- e -- i <-- Branch-A
f' -- g' <-- Branch-B
f -- g [abandoned]
(option 2: after j)
f' -- g' <-- Branch-B
/
a -- b -- c ------ h -- j <-- Master
/
d -- e -- i
f -- g [abandoned]
要使选项 2 发生,请运行:
git checkout Branch-B
git rebase Master
(我更喜欢在这里使用两个单独的命令,但如果你愿意,你可以拼写这个git rebase Master Branch-B
:额外的Branch-B
参数使git rebase
首先运行git checkout
。 请注意,我已经删除了名称Branch-A
:我们在这里不需要它。 此时您可能已删除它,也可能未删除它,如果没有,您可以稍后删除它。
若要使选项 1 发生,请运行:
git checkout Branch-B
git rebase Branch-A
这次我们需要名称Branch-A
才能轻松找到提交j
的哈希ID。 因此,如果要使选项 1 发生,并且不想运行git log
并剪切和粘贴哈希 ID,请至少在此时之前保持名称Branch-A
。 变基完成后,我们不再需要该名称Branch-A
,现在可以安全地删除了。
从技术上讲,我们在变基之前也不需要它,因为我们可以随时查找j
的哈希 ID:git log Master
从j
开始并向我们显示,然后向我们显示h
或i
之一,最终我们看到i
,因此看到它的哈希 ID。 因此,无论如何,我们都可以以艰难的方式找到它 - 但如果您保留名称一段时间,我们就不必这样做。
注意:如果您使用 GitHub 的"变基和合并"或"挤压和合并"点击按钮,则这些按钮不会执行标准合并。 相反,他们将提交复制到新的提交,类似于变基。 也就是说,他们将为您尝试合并的提交制作新的和据称改进的副本。 在这种情况下,你自己的现有名称都找不到正确的提交哈希 ID,因为您的所有名称仍然会记住您的原始提交及其哈希 ID,而不是 GitHub 将进行的副本/新提交。 因此,如果您确实使用 GitHub 的更高级的操作,则必须运行git fetch
从 GitHub获取新提交,然后使用其他名称或原始提交哈希 ID;您应该尽快放弃或修复自己的分支名称,以避免混淆哪些提交是原始提交,哪些是新的,据称是改进的副本。 (提交f9131d9
原始的,还是70abf32c
的?a31cf2a
与0449acd
呢? 哈希 ID 看起来完全随机,保持它们直截了当是......不好玩。
这种方法是"过度分支的"。只需在其中开发与分支 A 相关的新功能即可。不要创建分支 B。如果新功能转到主节点 - 提交分支 A 并合并到主节点。