为什么合并删除后 Git 特性分支仍然可见?
Why is the Git feature branch still visible after merge and deletion?
采取的步骤
我将 feature
分支合并回 master
并删除了 feature
分支。但它仍然出现在树中。
结果
SourceTree 中的树可视化在 删除功能分支之前:
SourceTree 中的树可视化在 删除功能分支后:
左侧列表中的 feature
分支如预期的那样消失了,树可视化中的标签也如预期的那样消失了。
问题
但是:
- 为什么还显示紫色部分?
- 我需要执行哪些 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
分支曾经存在:
问题
- 此次合并与之前的合并有何不同?
我想我大概拼凑了经过上述所有试验和错误后这些合并会发生什么,但如果有人真的能详细解释上述步骤的语义差异是什么,我将不胜感激。
删除分支时,您删除的是指向提交的指针,而不是提交本身。如果没有其他对提交的引用,那么提交最终可以被垃圾收集,但合并的提交会创建对该提交的引用(因为该提交是其父项)。
最初的 merge
工作流创建了一个有两个父提交的合并提交,第二个父提交仍然存在,即使指向它的分支不存在。
当您执行 git merge --squash
时,您实际上是在将 rebase
提交到目标分支,这为您提供了线性历史而不是双亲历史。对于该命令和 rebase
之间的区别,请查看 this question.
你仍然看到紫色的部分,因为你编辑了一个 git merge
,它创建了一个合并提交组装两个分支。由于分支已经分叉,这是一个 "non fast forward" 合并,这就是为什么历史仍然会显示这种树的原因。
你不想要紫色的部分?使用 git rebase
而不是 git merge
。你的情况:
git checkout master
git rebase feature
git branch -d feature
这将在分歧之前重播 feature
在 master
上的提交。您的历史日志中会有一条直线。
- 你做了一个
git merge --squash
,这很像一个 rebase - 但是你在一次提交中压缩了源分支的所有提交(在你的情况下你只有一个提交,所以它实际上并没有显示)
采取的步骤
我将 feature
分支合并回 master
并删除了 feature
分支。但它仍然出现在树中。
结果
SourceTree 中的树可视化在 删除功能分支之前:
SourceTree 中的树可视化在 删除功能分支后:
左侧列表中的 feature
分支如预期的那样消失了,树可视化中的标签也如预期的那样消失了。
问题
但是:
- 为什么还显示紫色部分?
- 我需要执行哪些 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
分支曾经存在:
问题
- 此次合并与之前的合并有何不同?
我想我大概拼凑了经过上述所有试验和错误后这些合并会发生什么,但如果有人真的能详细解释上述步骤的语义差异是什么,我将不胜感激。
删除分支时,您删除的是指向提交的指针,而不是提交本身。如果没有其他对提交的引用,那么提交最终可以被垃圾收集,但合并的提交会创建对该提交的引用(因为该提交是其父项)。
最初的 merge
工作流创建了一个有两个父提交的合并提交,第二个父提交仍然存在,即使指向它的分支不存在。
当您执行 git merge --squash
时,您实际上是在将 rebase
提交到目标分支,这为您提供了线性历史而不是双亲历史。对于该命令和 rebase
之间的区别,请查看 this question.
你仍然看到紫色的部分,因为你编辑了一个
git merge
,它创建了一个合并提交组装两个分支。由于分支已经分叉,这是一个 "non fast forward" 合并,这就是为什么历史仍然会显示这种树的原因。你不想要紫色的部分?使用
git rebase
而不是git merge
。你的情况:git checkout master
git rebase feature
git branch -d feature
这将在分歧之前重播 feature
在 master
上的提交。您的历史日志中会有一条直线。
- 你做了一个
git merge --squash
,这很像一个 rebase - 但是你在一次提交中压缩了源分支的所有提交(在你的情况下你只有一个提交,所以它实际上并没有显示)