git 如何在合并后重定基底?

nbysray5  于 2022-11-20  发布在  Git
关注(0)|答案(1)|浏览(131)

我们有一系列的事件:
1.创建分支A,并向其添加一些提交
1.时间流逝,数百个提交添加到master
1.主机合并到A
1.随着时间的推移,可能又有50个提交添加到master
有没有可能把第三步的合并变成一个重定基?如果没有别的,这将使即将到来的合并更简单,因为将有更少的历史来看。
我们还没有启用rerere。

lnxxn5zx

lnxxn5zx1#

请看下面的Git图:

A...C...D...F
^       ^   ^ master
 \       \
  G...H...I...J
              ^ feature

...表示“大量提交”。
假设我们想从本质上重定基,也就是说,把feature历史中的提交而不是master历史中的提交改革为master中提交的线性序列。这与我们在提交I时把master合并到feature中的事实相混淆。如果我们试图重定基,Git会搞砸,因为它试图在master上应用例如C,并发现冲突。
最好的方法是从this answer开始,为方便起见复制如下:

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分支包含masterJ中的所有更改。在步骤(3)之后,HEAD指向A,但我们的工作副本包含masterJ中的所有更改,并且步骤(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

此时,您可以重置为F分支并以更细粒度的方式(甚至使用git add --patch)重新应用J''中的更改。
另一种方法是使用read-tree,如this other answer中所述

git checkout master
git read-tree -u -m feature

this answer中剽窃的另一种方法是

git diff master > feature.patch
git checkout master
patch -p1 < feature.patch

相关问题