24

git branch --merged似乎与--squash 不能很好地配合使用。

如果你做一个 normal git merge,然后git branch --merged告诉你哪些分支已经被合并。但是,如果使用了 --squash 选项,情况并非如此,即使生成的树是相同的。

我怀疑这是一个 git 缺陷,并且想知道我是否缺少一些 git-fu,或者我是否误解了某些东西。

简而言之:我想使用 --squash,但也希望 git 告诉我我压入另一个分支的分支是否已被 --merged。

4

1 回答 1

26

你不能从这里到那里(正如指路的人所说)。更准确地说,它没有意义。

问题是它git merge --squash实际上并没有进行合并。假设您的分支历史看起来像这样,例如(带有分支topicdevel):

          H ⬅ I ⬅ J     <-- topic
        ⬋
⬅ F ⬅ G
        ⬉
          K ⬅ L         <-- devel

如果您签出devel并合并topic,您将获得一个新的合并提交M,其中包含合并的结果,并且M有两个父级:

          H ⬅ I ⬅ J     <-- topic
        ⬋         ⬆
⬅ F ⬅ G           ⬆
        ⬉         ⬆
          K ⬅ L ⬅ M     <-- devel

但是如果你使用git merge --squash topic你会得到一个新的提交(让我们将它标记S为壁球):

          H ⬅ I ⬅ J     <-- topic
        ⬋
⬅ F ⬅ G
        ⬉
          K ⬅ L ⬅ S     <-- devel

其中(正如您已经注意到的) commit 的内容(树)S使所有文件的输出与它们在 commit 中的相同M。但是没有从 S 到 的反向链接(父箭头)topic。这根本不是合并,它只是从 中获取所有更改topic,将它们压缩为单个更改,并将其添加为完全独立的提交。

现在,另一件事git merge --squash是它没有进行最终提交。因此,您可以创建.gitgit 将在“常规”合并中使用的文件,并进行提交,其中包含您在“真正”合并中获得的两个父级。然后你会得到......如果你运行,你会得到什么git merge topic,一个提交(标记它SM,没关系)再次具有相同的树,但现在有两个指向Land的父箭头,J就像M.

实际上, runninggit merge --squash几乎与 running 完全相同git merge --no-commit,除了合并完成时留下的跟踪文件(git commit使用其中一些来设置父级)。该squash版本不写入.git/MERGE.git/MERGE_HEAD.git/MERGE_MODE。(它确实创建.git/MERGE_MSG了 ,与 相同git merge --no-commit,它也创建了.git/SQUASH_MSG。)

因此,基本上,您可以选择:真正的合并(最终提交时有两个或更多父级),或壁球(相同的树组合机制,但最终提交时只有一个父级)。而且,由于git branch --merged通过查看存储在存储库中的每个提交的“父箭头”来工作,因此只有真正的合并才是真正的合并,所以只有真正的合并才能在以后发现git branch

于 2013-10-11T03:01:02.000 回答