正如标题所示,我对git merge --squash
和git merge --no-commit
之间的区别不是很清楚。
据我理解,在git merge
帮助页面中,这两个命令都会让我处于更新后的工作树状态,仍然可以进行编辑,最终提交(或多次提交)。
有人可以澄清一下这两个选项的区别吗?我应该在何时使用其中一个而不是另一个?
git merge --no-commit
git merge --squash
基本上,在最后没有这样的区别,但是看下面的草图,一旦你checkout master
分支
A---B---C topic
/ \
D---E---F---G---H master (from the documentation https://git-scm.com/docs/git-merge)
git merge topic
:将指定分支(自从与当前分支有所不同的历史分歧点开始)中的更改合并/重演到当前分支,并在一个新提交 H
中记录结果,同时记录两个父提交的名称和用户描述更改的日志消息。然后像往常一样将其推送到上游。$ git log --all --decorate --oneline --graph
* 72e576d (HEAD -> master) H Merge branch 'topic'
|\
| * dda0d97 (topic) C
| * 3471c39 B
| * cfb8410 A
* | a1c7e23 G
* | 5c0b97b F
|/
* c463d89 E
* 2312a5b D
$ git show HEAD -m
commit 72e576d (from a1c7e23) (HEAD -> master)
Merge: a1c7e23 dda0d97
H Merge branch 'topic'
diff --git a/A b/A
diff --git a/B b/B
diff --git a/C b/C
commit 72e576d (from dda0d97) (HEAD -> master)
Merge: a1c7e23 dda0d97
H Merge branch 'topic'
diff --git a/F b/F
diff --git a/G b/G
git merge --no-commit
:与上面相同,但是在创建新提交之前停止,让用户有机会检查和进一步调整合并结果。然后由您决定提交已添加到索引中的内容并像往常一样将其推送到上游。$ git log --all --decorate --oneline --graph
* f576f37 (HEAD -> master) H
|\
| * dda0d97 (topic) C
| * 3471c39 B
| * cfb8410 A
* | a1c7e23 G
* | 5c0b97b F
|/
* c463d89 E
* 2312a5b D
$ git show HEAD -m
commit f576f37 (from a1c7e23 ) (HEAD -> master)
Merge: a1c7e23 dda0d97
H
diff --git a/A b/A
diff --git a/B b/B
diff --git a/C b/C
commit f576f37 (from dda0d97) (HEAD -> master)
Merge: a1c7e23 dda0d97
H
diff --git a/F b/F
diff --git a/G b/G
git merge --squash
:工作区和索引状态就像进行了真正的合并一样(除了合并信息),但不进行提交,从而允许在当前分支的顶部创建单个提交。同样,像以前一样,由您来提交和推送到上游。$ git log --all --decorate --oneline --graph
* 118019a (HEAD -> master) H
* a1c7e23 G
* 5c0b97b F
| * dda0d97 (topic) C
| * 3471c39 B
| * cfb8410 A
|/
* c463d89 E
* 2312a5b D
$ git show HEAD -m
commit 118019a (HEAD -> master)
H
diff --git a/A b/A
diff --git a/B b/B
diff --git a/C b/C
注意: 快进式更新不会创建合并提交,因此,为确保您的分支不被更改/更新,请使用--no-ff
选项与--no-commit
选项。
git log --parents
命令查看一个提交的父节点(使用git log --merges
则只显示这种合并提交)。 - Philipp Wendler