这一定很明显,但我找不到任何方法。每本手册都描述了在现有分支的顶部或简单的交互式重基,仅此而已。假设,我有一个类似于这样的菱形git历史:
* 949430f Merge commit (D) (HEAD, mybranch)
|
| * e6a2e8b (C)
* | 3e653ff (B)
|/
* 9c3641f Base commit (A)
我想归档历史,比如:
* 949430f Combined commit (BCD)
|
* 9c3641f Base commit (A)
委员会B和C可能会被融化或丢弃,没关系,我只想保留结果。此外,我不想恢复提交,因为恶劣的冲突解决。
以下是我尝试过的东西:
1) 我不能通过简单地压扁B和C 来证明这一点
git rebase -i HEAD~2
...
p 3e653ff (B)
f e6a2e8b (C)
...
Could not apply a91f3a4
嗯,这在某种程度上是可以理解的,有一些冲突。
2) 我不能通过挤压来达到这个目的。
git rebase -i -p HEAD~3
...
pick 9c3641f Base commit (A)
f 3e653ff (B)
f e6a2e8b (C)
pick 949430f Merge commit (D)
...
error: unable to match a91f3a4...
3) 我甚至不能丢弃B和C
git rebase -i -p -m HEAD~3
...
pick 9c3641f Base commit (A)
#pick 3e653ff (B)
#pick e6a2e8b (C)
pick 949430f Merge commit (D)
...
error: Commit 949430f is merged but option -m is not set.
fatal: cherry-pick failed
Could not pick 4f3e6231b5cecf57434613ca3afd2a21ba375eb9
为什么?这是选项"-m"。。。
有人知道如何解决这个问题吗?
您想要的是git reset --soft
(加上aragaer指出的提交)。尽管问题中的情况不同,请参阅VonC的回答。
我会先尝试将提交图线性化,然后将它们压缩在一起:
$ git checkout commitA -b newbranch
$ git cherry-pick commitB
$ git cherry-pick commitC
[resolve any conflicts]
$ git rebase -i commitA
[change the command for commitC to 'squash']
git rebase -i 9c3641f^ # 1 before base commit
然后在交互式编辑器中
pick 9c3641f Base commit (A)
pick 3e653ff (B)
fixup e6a2e8b (C)
fixup 949430f Merge commit (D) (HEAD, mybranch)
事实上,我希望最后一个不会出现,因为根据我的经验,合并提交会在交互式重新基准期间消失。
这将把B和C压缩成一个承诺。D会消失,而且你并不真的想要它,因为它没有添加代码。
这将为您提供所需的输出。你错过的概念是,你需要保留第一个提交(pick),但如果你"修复"了其他两个,它们就会合并到其中。你需要给它们一些可以合并的东西,而不是基本提交。因此,您选择第二个,然后第三个合并到其中,从而提供两个提交。
你也可以做
git rebase -i 9c3641f
然后在交互式编辑器中看不到基本提交,但CCD_ 2和CCD_。