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

Why is the Git feature branch still visible after merge and deletion?

采取的步骤

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

结果

SourceTree 中的树可视化 删除功能分支之前:

SourceTree 中的树可视化 删除功能分支后:

左侧列表中的 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."

现在它显示了我最初的预期。一条直线,没有指示 feature 分支曾经存在:

问题

  1. 此次合并与之前的合并有何不同?

我想我大概拼凑了经过上述所有试验和错误后这些合并会发生什么,但如果有人真的能详细解释上述步骤的语义差异是什么,我将不胜感激。

删除分支时,您删除的是指向提交的指针,而不是提交本身。如果没有其他对提交的引用,那么提交最终可以被垃圾收集,但合并的提交会创建对该提交的引用(因为该提交是其父项)。

最初的 merge 工作流创建了一个有两个父提交的合并提交,第二个父提交仍然存在,即使指向它的分支不存在。

当您执行 git merge --squash 时,您实际上是在将 rebase 提交到目标分支,这为您提供了线性历史而不是双亲历史。对于该命令和 rebase 之间的区别,请查看 this question.

  1. 你仍然看到紫色的部分,因为你编辑了一个 git merge,它创建了一个合并提交组装两个分支。由于分支已经分叉,这是一个 "non fast forward" 合并,这就是为什么历史仍然会显示这种树的原因。

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

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

这将在分歧之前重播 featuremaster 上的提交。您的历史日志中会有一条直线。

  1. 你做了一个 git merge --squash ,这很像一个 rebase - 但是你在一次提交中压缩了源分支的所有提交(在你的情况下你只有一个提交,所以它实际上并没有显示)