Git 合并提交而不挤压与挤压选项
在日常工作中,我使用Git 合并提交而不挤压与挤压选项,git,merge,version-control,smartgit,Git,Merge,Version Control,Smartgit,在日常工作中,我使用SmartGit作为选择的客户端。然而,我的团队成员坚持使用git原生的非商业GUI。我们发现合并提交的外观存在一些差异 这些是SmartGit在请求合并分支时提供的选项: 在下图中,您可以看到我的示例SmartGit图形输出,其中包含: 单个主分支 使用合并提交选项将一个分支合并到主分支 一个分支与简单提交选项合并 其中一个分支(带有_merge _branch)通过行将分支与主分支连接起来,从而可视化合并操作。第二个(normal\u commit\u分支)没有
SmartGit
作为选择的客户端。然而,我的团队成员坚持使用git原生的非商业GUI。我们发现合并提交的外观存在一些差异
这些是SmartGit
在请求合并分支时提供的选项:
在下图中,您可以看到我的示例SmartGit图形输出,其中包含:
- 单个
主
分支
- 使用
选项将一个分支合并到主分支合并提交
- 一个分支与
选项合并简单提交
带有_merge _branch
)通过行将分支与主分支连接起来,从而可视化合并操作。第二个(normal\u commit\u分支
)没有
问题是,如何在本机git命令中实施这两种行为?也就是说,这两次提交之间有什么区别?这两种合并之间的区别仅在提交历史中有所不同(如图中的日志所示) 让我们用图表来说明。合并前,假设提交历史记录如下所示:
A---B---C---D master
\
E---F---G develop
合并提交(多个父级):
使用的命令是git merge branchname
。这是合并两个分支的默认方式
当您在SmartGit(git merge develop
)中通过合并提交将develop
分支合并到master
分支时,提交历史记录将为:
A---B---C---D---M master
\ /
E---F---G develop
A---B---C---D---M master
\
E---F---G develop
简单提交(单亲“挤压”):
它使用--squash
选项合并两个分支,使用的命令是git merge branchname--squash
生成工作树和索引状态,就像发生了真正的合并一样(合并信息除外),但实际上不生成
提交、移动标头或记录$GIT\u DIR/MERGE\u HEAD(以导致
下一个git commit命令(用于创建合并提交)。这允许您
在当前分支上创建一个提交,其效果为
与合并其他分支相同(如果是章鱼,则合并更多分支)
当您在SmartGit(git merge develop--squash
)中通过简单提交将develop
分支合并到master
分支时(git merge develop--squash
),它会将develop
分支中的更改作为一个新的普通提交(就好像发生了真正的合并),提交历史记录如下:
A---B---C---D---M master
\ /
E---F---G develop
A---B---C---D---M master
\
E---F---G develop
合并提交
只是提交
,但区别在于它们有多个父级。
正如您所知,提交可能有父提交,也可能没有父提交,事实上,
合并提交
是具有多个父提交
的提交可能与我从未使用过的父提交重复,但使用挤压选项的git merge会删除存在第二个父分支的任何痕迹。如果您遵循复制链接,您将看到一些您可能希望使用它的示例。没有挤压选项的合并是git merge
的默认行为。为了补充@Marina给出的奇妙答案,在某些集成(在我的例子中是GitLab)的情况下,如果使用-squash
提交到父分支中,内部合并请求系统将无法检测合并的分支。因此,在一方面,您有更清晰的历史记录,但对合并源的检测有点困难。我认为,一个警告是正确的:Squash提交丢失历史记录!如果进行合并,git
将知道导致功能集成的所有中间步骤,git bisect
将能够确定这些中间步骤之一的回归。如果挤压,您的功能分支将成为git的一个黑匣子,git bisect
将只能指出包含整个功能开发的挤压提交。最好全心全意地接受git的DAG历史模型,它将为您省去很多麻烦。