Git壁球并合并

Gre*_* Ho 5 git merge squash

谁能告诉我这两个命令之间的区别:

git merge --squash
Run Code Online (Sandbox Code Playgroud)

git merge --no-ff 
Run Code Online (Sandbox Code Playgroud)

Col*_*lin 7

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

git merge --squash

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

--squash--no-squash

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

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

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

A --> B --> C
Run Code Online (Sandbox Code Playgroud)

合并提交有多个父项,它是树中你将两个或多个谱系放在一起的地方:

A --> B --> F
           /
C --> D - /
Run Code Online (Sandbox Code Playgroud)

看看如何A,BC,并且D是常规提交,但是它F是一个合并提交,因为它有多个父项(BD)?这就是git merge --no-ff产生的.它迫使Git创建一个合并提交,将两个历史结合在一起.

git merge --squash会做一些不同的事情.它可以防止Git创建合并提交,但仍然会进行更改CD进行更改,因此您的树看起来像这样:

A --> B --> F'

C --> D 
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

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

A --> B --> C --> D --> E
                        |
                     'topic'
                     'master'
Run Code Online (Sandbox Code Playgroud)

主题和主人都指向同一个分支.现在,某些工作流程规则要求您在每次合并回来时创建合并提交master.这保留了分支的历史.你会得到关于它应该如何完成的论据,但我不会在这里讨论.

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

                   'master'
                       |
A --> B -------------> F
       \              /
        C --> D --> E
                    |
                 'topic'
Run Code Online (Sandbox Code Playgroud)

F新的合并提交--no-ff力Git 在哪里创建.