我们有这样的一系列事件:
- 创建分支 A,并向其添加一些提交
- 时间流逝,数百个提交添加到主节点
- 主节点合并为 A
- 时间流逝,也许还有 50 个提交添加到 master
是否可以将步骤 3 中的合并转换为变基?如果不出意外,这将使即将进行的合并更简单,因为要查看的历史会更少。
我们尚未启用重新设置。
考虑以下 Git 图:
A...C...D...F
^ ^ ^ master
G...H...I...J
^ feature
这。。。表示"大量提交"。
假设我们想要本质上变基,即在功能的历史中而不是在主的历史上获取提交,并将它们作为主控中的线性提交序列进行改革。这让我们在提交时将 master 合并到功能I
这一事实令人困惑。如果我们尝试变基,Git 会搞砸,因为它试图应用例如 C
在主人之上,发现冲突。
最好的方法是从这个答案,为方便起见,复制如下:
git checkout feature
git branch -m feature-old
git checkout main
git checkout -b feature
git merge --squash feature-old
git commit
<小时 />我们可以通过从feature
中获取实际更改并将它们打包到新的提交中来解决此问题。这是一种仅使用非常基本的 Git 命令执行此操作的方法:
(1) git checkout feature
(2) git merge master
(3) git reset A
(4) git add -A # This stages all working copy changes
(5) git commit -m "Every change between A and J"
在步骤 (2( 中,feature
分支具有master
和J
的所有更改。在步骤 (3( 之后,HEAD 指向 A
,但我们的工作副本具有来自 master
和 J
的所有更改,步骤 (4( 和 (5( 分阶段并提交这些更改。
此时,我们的图表如下所示
A...C...D...F
^ ^ master
J'
^ feature
请注意,J'
包含 A...F
中的所有内容。现在我们做到了
git rebase master
Git 很乐意将 J'
中的更改作为新的提交J''
,但唯一要添加的更改是 G...J
中的更改,因为其他更改已经在 master 中。所以现在我们有
A...F<--J''
master^ ^feature
随着我们feature
分支中的所有更改都压缩到提交J''
中。此时,如果需要,您可以重置为F
并以更精细的方式(甚至使用 git add --patch
(重新应用J''
中的更改。
另一种做基本相同事情的方法是使用read-tree
,如另一个答案中所述
git checkout master
git read-tree -u -m feature
<小时 />从这个答案中窃取的另一种做同样事情的方法
git diff master > feature.patch
git checkout master
patch -p1 < feature.patch