如何重写到覆盖历史的分支?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何重写到覆盖历史的分支?相关的知识,希望对你有一定的参考价值。
说我有分支1
与提交A
。
1: A
从1开始,我创建了另一个分支2
。
2: A
在2
上,我添加了一个提交。
2: A->B
然后在1
,我做了一些改变和git commit --amend
,覆盖A
。
1: C
在2
,我想要在1
上进行这些新的更改,并希望将我的更改从B
应用到C
。但是,从我的理解,git将看到分支2
有新提交A
和B
,并尝试在C
上应用这两个提交。因此,当我完成变基,2
将会是这样的
2: C->A->B
当我真正想要的是C->B
。
处理这种情况的正确方法是什么?到目前为止,我一直在处理这个问题的方法是从1
创建一个新分支,然后从B
挑选2
。但是,当2
不仅仅有一个新的提交时,这看起来有点像hacky,并不是那么简单。
让我们更传统地说明这一点,看看发生了什么。
如果A是第一次提交事情变得复杂,那么我将添加一个祖先Z.
假设我有提交A的分支1。
Z - A [1]
从1开始,我创建另一个分支,2。
Z - A [1][2]
在2,我添加一个提交。
Z - A [1]
B [2]
然后在1,我做了一些更改和git commit --amend,覆盖A.
事情变得如此糟糕。
C [1]
/
Z - A
B [2]
Git从不“覆盖”提交。它不能。提交ID是提交内容及其所有祖先的校验和。 commit --amend
(以及rebase
)所做的是创建新的提交并假装它一直都是这样。
但旧的承诺仍然存在。如果有任何东西作为祖先,就像这里的分支2一样,它将是可见的。
在2,我希望在1上进行这些新的更改,并希望将我的更改从B应用到C.但是,根据我的理解,git将看到分支2具有新的提交A和B,并尝试应用这两个提交在C语言之上。所以当我完成变基础时,2将看起来像2:C-> A-> B当我真正想要的是C-> B.
这里的问题是因为commit --amend
分支1和分支2不再有A作为共同的祖先。它现在是Z.如果你试图将2变为1,它会将A和B都放在C之上。
A1 - B1 [2]
/
C [1]
/
Z - A
B
虽然这可能有效,但也可能导致混乱的冲突。你必须使用更精确的rebase命令让Git知道你真正想要的是什么。由于C实际上是一个重写的A,你真正想要的是A之后的所有内容。
git rebase --onto 1 A..2
结果将是你想要的。
B1 [2]
/
C [1]
/
Z - A
B
(A和B将不可见,它们最终将被垃圾收集。)
如果你认为这很复杂并且充满危险,那就是!
这就是为什么最好不要修改或修改你的“稳定”分支,通常是master
。相反,只需使用普通提交或功能分支进行更大的更改。然后应用更新分支的正常过程。
以上是关于如何重写到覆盖历史的分支?的主要内容,如果未能解决你的问题,请参考以下文章