你不能从这里到那里(正如指路的人所说)。更准确地说,它没有意义。
问题是它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
其中(正如您已经注意到的) commit 的内容(树)S
使所有文件的输出与它们在 commit 中的相同M
。但是没有从 S 到 的反向链接(父箭头)topic
。这根本不是合并,它只是从 中获取所有更改topic
,将它们压缩为单个更改,并将其添加为完全独立的提交。
现在,另一件事git merge --squash
是它没有进行最终提交。因此,您可以创建.git
git 将在“常规”合并中使用的文件,并进行提交,其中包含您在“真正”合并中获得的两个父级。然后你会得到......如果你运行,你会得到什么git merge topic
,一个提交(标记它S
或M
,没关系)再次具有相同的树,但现在有两个指向L
and的父箭头,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
。