将提交拆分为现有提交

时间:2020-08-13 10:56:11

标签: git git-rebase git-rewrite-history

我有一个分支,其中包含多个提交:

A --- B --- C --- D
                  ^
                 HEAD

我已经完成了该分支的工作并准备了拉取请求。但是我对当前的历史不满意:

  • C正在修改很多本来可以提交给A和B的文件
  • D正在解决一些独立的问题,应保留为

我正在寻找一种将C分为A和B而又不会破坏D的干净方法。

2 个答案:

答案 0 :(得分:1)

您需要重新设置基准两次:

  • 首先,使用git rebase -i HEAD^4运行交互式变基
  • 在编辑器窗口中,找到要拆分的提交,并将第一个单词pick替换为eedit的缩写)
  • 保存并退出编辑器,在您设置了要编辑的提交后,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更改为ssquash的缩写) )。
  • Cb的行移动到提交B的行下方,并将其设置为压入B
  • git rebase --continue

答案 1 :(得分:1)

我将在要使用的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