问题描述
我有一个分支,其中包含多个提交:
A --- B --- C --- D
^
HEAD
我已经完成了该分支的工作并准备了拉取请求。但是我对当前的历史不满意:
- C正在修改很多本来可以提交给A和B的文件
- D正在解决一些独立的问题,应保留为
我正在寻找一种将C分为A和B而又不会破坏D的干净方法。
解决方法
您需要重新设置基准两次:
- 首先,使用
git rebase -i HEAD^4
运行交互式变基 - 在编辑器窗口中,找到要拆分的提交,并将第一个单词
pick
替换为e
(edit
的缩写) - 保存并退出编辑器,在您设置了要编辑的提交后,rebase将为您提供
- 使用
git reset HEAD~
重置提交
- 现在您的更改已取消,您可以根据需要提交它们
- 使用
git add -p
仅在文件中添加一些更改很有用 - 创建两个提交,一个提交要合并到A中,另一个要合并到B中
-
git rebase --continue
现在,您已将提交分为两部分,历史记录应如下所示:
A --- B --- Ca --- Cb --- D
^
HEAD
您现在可以启动第二个基准,以将Ca
合并到A
中,并将Cb
合并到B
中:
-
git rebase -i HEAD^4
- 在编辑器中,将提交
Ca
的行移到提交A
的行下方,并将pick
更改为s
(squash
的缩写) )。 - 将
Cb
的行移动到提交B
的行下方,并将其设置为压入B
-
git rebase --continue
我将在要使用的C上创建一个temp
分支,让我们假设main在D上(未指定,但是):
git branch -b temp C
# let's go back to A,keeping _all_ of C's content so you can decide what to keep:
git reset --soft A
# now get the files the way you would like to get it for A (you can compare with A and B,just so that you _really_ get what you want.
# when you are done
git commit -m "new A"
# temp is on the new A
# let's go back to C
git checkout C
# let's put it on top of temp
git reset --soft temp
# Get the files you want the to be on B (compare with HEAD~1 and B.. and C)
# when you are done
git commit -m "new B"
# let's put temp where we are
git branch -f temp
# finally,let's move whatever is left over from C that is not part of B
git checkout C
git reset --soft temp
git commit -m "New C"
git branch -f temp
# at this moment C and temp are exactly the same
git checkout temp
git cherry-pick D
# temp is like the branch you want
...就是这样。
如果实际上C是您希望B变成的样子,但对A进行了一些更改,则遵循有关“新A”的方法,然后
git checkout C
git reset --soft temp
git commit -m "New B"
git branch -f temp
git checkout temp
git cherry-pick D