为什么在合并和删除之后Git特性分支仍然可见?

7

步骤

我将feature分支合并回master并删除了feature分支。但是它仍然显示在树中。

结果

在删除功能分支之前,SourceTree中的树可视化: Tree before deleting the feature branch

在删除功能分支后,SourceTree中的树可视化:Tree after deleting the feature branch

左侧列表中的feature分支已消失,如预期的那样,树可视化中的标签也已消失,同样符合预期。

问题

但是:

  1. 为什么紫色部分仍然显示?
  2. 我需要执行哪些Git命令才能不再看到紫色部分?两个小节后面我可能已经回答了这个问题。

我理解上图中的最终提交有两个父提交。 但我不明白为什么发生在特性分支上的紫色提交不在master上的最终合并提交中(我想,这意味着删除它后紫色分支不应再可见)。

通过命令行重放步骤(而不是SourceTree)

我在命令行上重放了它(只是为了检查SourceTree是否如我所想)。最后一步是git merge feature。情况相同:

命令行中的树可视化

使用--squash选项的尝试

我撤销了最后一次合并,并尝试了这个:

git merge --squash feature
git commit "Squashed merge"
git delete -D feature # Note that -d did not work; it said "error: The branch 'feature' is not fully merged."

现在它显示了我最初期望的内容。一条直线,没有任何特性分支的迹象:

Squash后的直树线

问题

  1. 这个合并与之前的合并有何不同?

我猜我在上面的所有尝试和错误之后已经概括了这些合并的发生过程,但如果有人能详细解释上述步骤的语义差异,我将不胜感激。

2个回答

4
当您删除分支时,您实际上是在删除指向提交的指针,而不是提交本身。如果没有对该提交的其他引用,那么该提交最终可能会被垃圾回收,但合并提交会创建对该提交的引用(因为该提交是其父提交)。
最初的“合并”工作流创建一个具有两个父级的合并提交,即使指向它的分支不存在,第二个父级提交仍然存在。
当您执行“git merge --squash”时,您实际上是在将您的提交重新基于目标分支进行“变基”,这会给您线性历史记录,而不是双亲历史记录。关于该命令和“变基”的区别,请看此问题

不错的链接。它说git merge --squash会"不标记任何合并关系",这是我不理解的部分。谢谢! - Lernkurve
@Lernkurve。欢迎您。如果您想重写您的历史记录,您需要确定您希望您的历史记录看起来像什么。例如,您是想在您的“主”分支上有十几个提交,还是只有一个提交相当于所有这些提交? - merlin2011
我对第一个例子很感兴趣,因为我可以将十几个提交保留在master的顶部。但出于学习目的,我也对只有一个提交等效于所有提交的例子感兴趣。 - Lernkurve
@Lernkurve,创建一个新分支并使用Squash / Rebase,然后从主分支上cherry-pick其余的提交。 - merlin2011
成功了! :-) 我刚刚使用ranges进行了大量的挑选。太棒了!非常感谢。 - Lernkurve

4
  1. 你仍然会看到紫色的部分,因为你做了一个git merge, 这个命令创建了一个合并提交将两个分支组合在一起。由于分支已经分叉,这是一个“非快进”合并,这就是为什么历史记录仍然显示这种树状结构的原因。

  2. 你不想要紫色的部分吗?使用git rebase而不是git merge。在你的情况下:

    • git checkout master
    • git rebase feature
    • git branch -d feature

这将在分叉之前将feature上的提交重放到master上。你的历史记录中将会有一条直线。

  1. 你使用了git merge --squash,它与rebase非常相似-但是你正在将源分支的所有提交压缩成一个提交(在你的情况下只有一个提交,所以它不会真正显示)

你的第二点非常有帮助,它解释了如何避免在第一次合并时出现紫色部分。然而,假设我已经执行了 git merge feature 并在 master 上进行了另外十几个提交:那么在游戏晚期如何消除紫色部分呢?再进一步假设我还没有推送任何东西,因此重写历史是可以接受的。那么该怎么做呢? - Lernkurve
1
假设您没有推送任何内容,这仍然是可行的。如果在此基础上有十几个提交,则取决于...您有两个解决方案:1)这些提交与合并没有太多关联吗?您可以进行交互式变基(似乎有点困难)- 2)在合并之前只需git reset,将您的修改git stash,然后git rebase feature,最后git stash pop以检索您的修改,并重新执行您的提交。 - topheman
@topheman 尝试第二点:重置后,“feature”分支被删除了,我再也看不到它了? - powder366
不是重置,而是变基:这就是为什么在你想从特性分支导入代码到主分支的情况下,你将不再需要这个特性分支。 - topheman
虽然高层概念大多正确,但我认为你的第二点本应是相反的?git checkout featuregit rebase mastergit checkout mastergit branch -d feature - RayLuo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接