5

谁能告诉我这两个命令有什么区别:

git merge --squash

git merge --no-ff 
4

1 回答 1

7

我认为你的问题表明有点误解。--no-ff并且--squash不是对立的,而是微妙地不同的操作。阅读时请记住这一点。

git合并--壁球

合并的帮助页面说明以下内容--squash

--squash--no-squash

生成工作树和索引状态,就好像发生了真正的合并一样(合并信息除外),但实际上并不进行提交或移动 HEAD,也不记录 $GIT_DIR/MERGE_HEAD 以导致下一个 git commit 命令创建合并犯罪。这允许您在当前分支之上创建一个提交,其效果与合并另一个分支相同(或者在章鱼的情况下更多)。

使用 --no-squash 执行合并并提交结果。此选项可用于覆盖 --squash。

这有点令人困惑,并且需要一些关于git. 首先,我们需要了解常规提交和合并提交之间的区别。常规提交有一个父级,并且只是应用于其之前的提交的变更集:

A --> B --> C

合并提交有多个父级,它是树中的一个位置,您将两个或多个谱系放在一起:

A --> B --> F
           /
C --> D - /

看看A, B, C, 和D是如何常规提交,但是F是合并提交,因为它有多个父级 (BD)?这就是git merge --no-ff会产生的。它强制 Git 创建一个合并提交以将两个历史记录放在一起。

git merge --squash会做一些不同的事情。它阻止 Git 创建合并提交,但仍会拉入更改CD进行更改,因此您的树如下所示:

A --> B --> F'

C --> D 

F'包含更改CD进行了更改,但没有迹象表明您在存储库中合并了两棵树。

git 合并 --no-ff

--no-ff是一个略有不同的操作。即使它不是真的必要,它也会强制 Git 创建一个合并提交。作为参考,这是手册必须说的内容--no-ff,它是相反的--ff-only

--no-ff

即使合并解析为快进,也要创建合并提交。

--ff-only

拒绝合并并以非零状态退出,除非当前 HEAD 已经是最新的或者可以将合并解析为快进。

要理解,最好看一个例子:

A --> B --> C --> D --> E
      |                 |
    'master'          'topic'

如果你有这棵树,在 master 分支上并运行git merge,Git 将执行所谓的“快进”合并。由于这两个历史之间没有分歧,Git 可以将master分支移动到其所在的位置,topic而无需做任何有趣的事情。它看起来像这样:

A --> B --> C --> D --> E
                        |
                     'topic'
                     'master'

topic 和 master 都指向同一个分支。现在,一些工作流程规则要求您在每次合并回master. 这样可以保留分支的历史。无论哪种方式,您都会就应该如何完成而争论不休,但我不会在这里讨论这些。

如果你git merge --no-ff在同一棵树上使用,它会强制 git 创建一个合并提交,给你一个像这样的树:

                   'master'
                       |
A --> B -------------> F
       \              /
        C --> D --> E
                    |
                 'topic'

F新的合并提交--no-ff强制 Git在哪里创建。

于 2014-05-12T19:19:13.520 回答