如何合并git分支以使主题提交成为孤立的?

时间:2012-01-13 09:30:23

标签: git

我还在加速使用Git的一些更高级的功能......

鉴于以下历史记录,我如何清理主题分支合并,以便它们作为单个提交出现在历史记录中?

[master] - - - - - - - C - - -
   \
   [feature] - A - - B - - D -

理想情况下,我想在D处使用[master]重新设置[feature],然后将[feature]合并到[master]中,让A和B成为孤儿。

我以为我可以通过以下方式做到这一点:

$ git rebase master # on feature branch
$ git co master
$ git merge --no-ff feature

然后使用

清理孤立的提交
$ git gc --prune=now --aggressive

尽管如此,在历史上仍然留下A和B - 我错过了什么吗?

4 个答案:

答案 0 :(得分:3)

如果我重新绘制图表以将分支标记放在分支的顶端(这反映了分支的实际表示),那么您的原始情况是:

o --- C (master)
 \
   --- A --- B --- D (feature)

如你所描述的那样在与--no-ff重新定位和合并之后,你现在拥有:

o --- C ------------------ M (master)
 \      \                 /
  \       A' --- B' --- D' (feature)
   \
    --- A --- B --- D

据我了解,您现在要确保ABD从您的存储库中消失。首先,我想说我强烈建议您不要担心这些提交。

但是,如果你真的想摆脱它们,那么你必须确保它们真的无法访问,或者git gc --prune=now --aggressive不会删除它们。实际上,它们仍然会被feature的reflog指向(至少)。有许多方法可以使reflog中的条目到期,例如:用:

git reflog expire --expire=now feature

...或更安全的选项应该是将the config variable gc.reflogexpireunreachable设置为now并使reflog过期:

git config gc.reflogexpireunreachable
git reflog expire feature

在任何一种情况下,您都需要再次运行git gc --prune=now --aggressive

然而,重申我上面所说的,我不会这样做 - 那些提交并没有伤害任何人,使用git时reflog是一个有价值的安全网。

答案 1 :(得分:1)

如果你想“融合”A,B和D,你可以使用交互式rebase。

如果您的分支feature位于master之上(在此分支上发布git rebase master之后),请执行以下操作:

git rebase -i master

然后,在将在编辑器中打开的文件中,将提交A和B上的pick替换为squash。然后Git将A和B压入D,编辑器将弹出所有压缩提交的提交消息。

答案 2 :(得分:1)

如果要将分支的效果折叠为单个提交,则从master执行:

git merge --squash feature
git commit

虽然恕我直言可以保持分支上的个人提交完好无损,但实际上大多数时候都是一个很好的功能。

或者,你可以在分支上使用git rebase -i并告诉它将所有提交压缩在一起,然后将压扁的结果合并到master上。

答案 3 :(得分:0)

为什么会删除A和B?

git rebase master将使功能从master的提示分支出来,当你提交时,来自feature的所有提交都将成为master。因此,您将看到A和B(实际上是A'和B')

并且git gc与您在历史记录中看到的内容没有任何关系。它删除了悬空提交(可以是A和B,但你现在拥有A'和B')

如果您希望它们作为单一提交,请尝试使用--no-commit选项或查看其他替代方案,例如git rebase -i(和压缩)