为什么合并和删除后Git功能分支仍然可见?

时间:2015-09-24 20:39:13

标签: git git-branch git-merge

采取的步骤

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

结果

在删除功能分支之前

SourceTree 中的树可视化: Tree before deleting the feature branch

删除功能分支后

SourceTree 中的树可视化: Tree after deleting the feature branch

左侧列表中的feature分支已按预期消失,树形可视化中的标签也已按预期消失。

问题

可是:

  1. 为什么紫罗兰部分仍然显示?
  2. 我需要执行哪些Git命令才能看到紫色部分?我可能会在下面的两个部分回答这个问题。
  3. 我知道上面截图中的最终提交有两个父母。 但我不明白为什么在功能分支上发生的紫罗兰提交不在master的最终合并提交内(我认为,这意味着紫罗兰分支不应该是可见的删除后再删除。)

    从命令行(而不是SourceTree)重播步骤

    我在命令行上重播它(只是为了检查SourceTree是否做了我认为它做了什么),最后一步是git merge feature。同样的情况:

    Tree visualisation on the command line

    使用--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分支存在:

    Straight tree line after --squash

    问题

    1. 此合并与先前的合并有何不同?
    2. 我想我在上述所有试验和错误之后将这些合并发生的事情拼凑在一起,但如果有人能够真正详细解释上述步骤的语义差异,我将不胜感激。

2 个答案:

答案 0 :(得分:4)

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

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

执行git merge --squash时,您实际上会将rebase提交到目标分支,这会为您提供线性历史记录而不是双父历史记录。有关该命令与rebase之间的区别,请查看this question

答案 1 :(得分:4)

  1. 你仍然会看到紫色部分,因为你选择git merge,这会创建一个合并提交来组合两个分支。由于分支已经分歧,这是一个“非快进”合并,这就是为什么历史仍然会显示这种树。

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

    • git checkout master
    • git rebase feature
    • git branch -d feature
  3. 这会在分歧之前重播feature master的提交。您的历史记录日志中会有一条直线。

    1. 你做了一个git merge --squash非常类似于一个rebase - 但是你在一次提交中压缩了源代码分支的所有提交(在你的情况下你只有一次提交,所以它没有真正显示)