如何在 Git 中线性化 "splintered" 合并历史?
How to linearize "splintered" merging history in Git?
一定很明显,但是我没找到办法。每本手册都描述了在现有分支的顶部进行变基或简单的交互式变基,仅此而已。假设,我有一个像这样的菱形 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 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 reset --soft
(加上). Despite the different circumstances in the question, see this answer by VonC.
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 会消失,而且你真的不想要它,因为它没有添加代码。
这将为您提供所需的输出。您错过的概念是您需要保留第一个提交(选择),但如果您 "fixup" 其他两个,它们将合并到其中。你需要给他们一些东西来合并到不是基本提交的东西中。所以你选择第二个,然后第三个合并到它给你两个提交。
你也可以
git rebase -i 9c3641f
然后就不会在交互式编辑器中看到基本提交,但 pick
和 fixup
对于其余行将是相同的。
一定很明显,但是我没找到办法。每本手册都描述了在现有分支的顶部进行变基或简单的交互式变基,仅此而已。假设,我有一个像这样的菱形 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 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 reset --soft
(加上
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 会消失,而且你真的不想要它,因为它没有添加代码。
这将为您提供所需的输出。您错过的概念是您需要保留第一个提交(选择),但如果您 "fixup" 其他两个,它们将合并到其中。你需要给他们一些东西来合并到不是基本提交的东西中。所以你选择第二个,然后第三个合并到它给你两个提交。
你也可以
git rebase -i 9c3641f
然后就不会在交互式编辑器中看到基本提交,但 pick
和 fixup
对于其余行将是相同的。