Git壁球并合并

时间:2014-05-12 18:55:26

标签: git merge squash

有人可以告诉我这两个命令之间有什么区别:

git merge --squash

git merge --no-ff 

1 个答案:

答案 0 :(得分:6)

我认为你的问题表明有点误会。 --no-ff--squash不是对立的,而是略有不同的操作。在阅读时请记住这一点。

git merge --squash

help page for merge说明以下关于--squash

的内容
  

--squash--no-squash

     

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

     

使用--no-squash执行合并并提交结果。这个选项   可以用来覆盖--squash。

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

A --> B --> C

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

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

了解ABCD是如何进行常规提交,但F是合并提交,因为它有多个父级( BD)?这就是git merge --no-ff会产生的。它迫使Git创建一个合并提交,将两个历史结合在一起。

git merge --squash会做一些不同的事情。它会阻止Git创建合并提交,但仍然会引入所做的更改CD,因此您的树看起来像这样:

A --> B --> F'

C --> D 

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

git merge --no-ff

--no-ff是一个稍微不同的操作。它迫使Git创建合并提交,即使它不是真的有必要。作为参考,这里有关于--no-ff及其相对--ff-only的手册所说的内容:

  

--no-ff

     

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

     

--ff-only

     

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

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

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

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

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

主题和主人都指向同一个分支。现在,某些工作流程规则要求您在每次合并回master时创建合并提交。这保留了分支的历史。你可以在任何方面得到论证,但我不会在这里进入。

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

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

F是新的合并提交--no-ff迫使Git创建。