我还在加速使用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 - 我错过了什么吗?
答案 0 :(得分:3)
如果我重新绘制图表以将分支标记放在分支的顶端(这反映了分支的实际表示),那么您的原始情况是:
o --- C (master)
\
--- A --- B --- D (feature)
如你所描述的那样在与--no-ff
重新定位和合并之后,你现在拥有:
o --- C ------------------ M (master)
\ \ /
\ A' --- B' --- D' (feature)
\
--- A --- B --- D
据我了解,您现在要确保A
,B
和D
从您的存储库中消失。首先,我想说我强烈建议您不要担心这些提交。
但是,如果你真的想摆脱它们,那么你必须确保它们真的无法访问,或者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
(和压缩)