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

如何合并git分支以使主题提交成为孤立的?,git,Git,我仍然在学习Git的一些更高级的特性 鉴于以下历史记录,我如何清理主题分支合并,使它们以单个提交的形式出现在历史记录中 [master] - - - - - - - C - - - \ [feature] - A - - B - - D - 理想情况下,我希望在d处用[master]重新设置[feature]的基址,然后将[feature]合并到[master],使A和B成为孤立状态 我想我可以通过以下方式做到这一点: $ git rebase master # on featur

我仍然在学习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仍然保留在历史中——我遗漏了什么吗?

为什么它会删除A和B

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

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

如果希望它们以单次提交的形式出现,请尝试使用
--no commit
选项,或者查看其他选项,如
git-rebase-i
(和squash)

如果希望“融合”A、B和D,可以使用交互式的rebase

如果您的分支机构
功能
位于
主控
之上(在您在此分支机构上发布
git-rebase-master
后,将位于主控之上),请执行以下操作:


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

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

o --- C (master)
 \
   --- A --- B --- D (feature)
正如您所描述的,在重定基址并与
--无ff
合并后,您现在拥有:

o --- C ------------------ M (master)
 \      \                 /
  \       A' --- B' --- D' (feature)
   \
    --- A --- B --- D
据我所知,您现在需要确保
A
B
D
从存储库中消失。首先,我要说的是,我强烈建议您不要担心这些承诺

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

git reflog expire --expire=now feature
。。。或者更安全的选择应该是将
gc.reflogexpireunreachable
设置为
now
并使reflog过期:

git config gc.reflogexpireunreachable
git reflog expire feature
在这两种情况下,您都需要再次运行
git-gc--prune=now--aggressive


但是,为了重申我上面所说的,我不会这么做-这些提交不会伤害任何人,而且在使用git时,reflog是一个有价值的安全网。

如果您想将分支的效果压缩为单个提交,那么从master开始:

git merge --squash feature
git commit
尽管IMHO能够保持分支上的单个提交完好无损实际上在大多数情况下都是一个很好的特性


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

请删除您的一个答案。他们几乎一样!谢谢你的建议和解释
git merge --squash feature
git commit