git branch --merged
似乎与--squash没有很好的配合。
如果您执行正常git merge
,则git branch --merged
会告诉您哪些分支已合并。但是,如果使用--squash选项,则情况并非如此,即使结果树是相同的。
我怀疑这是一个git缺陷,想知道是否有一些git-fu我错过了,或者我是否误解了一些东西。
简而言之:我想使用--squash,但也希望git告诉我,我压扁的另一个分支是否已经过了。
答案 0 :(得分:15)
你不能从这里到达那里(正如发表指示的同事所说)。更准确地说,它没有意义。
问题是git merge --squash
实际上并没有进行合并。例如,假设您的分支历史记录是这样的(使用分支topic
和devel
):
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
其中(如您所述)提交S
的内容(树)使得所有文件与提交M
中的文件相同。但是没有从S到topic
的反向链接(父箭头)。它根本不是合并,它只是从topic
获取所有更改,将它们压缩为单个更改,并将其添加为完全独立的提交。
现在,关于git merge --squash
的另一件事是它没有进行最后的提交。因此,您可以创建git将在“常规”合并上创建的.git
文件,并执行具有您将在“真正”合并上获得的两个父级的提交。然后你会得到......如果你运行git merge topic
,提交(标记为S
或M
,无关紧要)再次拥有相同的树,你会得到... ,但现在有两个父箭头,指向L
和J
,就像M
一样。
实际上,运行git merge --squash
与运行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
之后只能发现真正的合并。