git merge 和 rebase 的区别
分支的合并
分支的合并主要有两种方法:merge 和 rebase,例如 release
分支或 hotfix
分支测试完成后,最后要合并回 master
分支,使用这两种方法,合并后分支的历史记录会有很大的差别,本文主要详细论述了这两种方法的差异以及使用场景。
merge
假设有两个分支:bugfix
分支是从 master
分支分叉出来的。下面主要分两种情况来讨论 merge
操作。
master 没有新的提交
如下图所示:

在 master
分支上执行一下命令会合并 bugfix
分支到 master
分支:
git merge bugfix # 等价于 git merge --ff bugfix
如果 master
分支的状态没有被更改过,那么这个合并是非常简单的。 bugfix
分支的历史记录包含 master
分支所有的历史记录,所以通过把 master
分支的指针向前 移动 到 bugfix
的最新分支上,Git 就会合并。这样的合并被称为 fast-forward
(快进)合并。

换句话说,如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward)。
执行合并时,如果设定了 non fast-forward
选项,即使在能够 fast-forward
合并的情况下也会生成新的提交并合并。
git merge --no-ff bugfix
如图所示:

master 也有新的提交
master
分支的历史记录有可能在 bugfix
分支分叉出去后有新的更新。这种情况下,要把 master
分支的修改内容和 bugfix
分支的修改内容汇合起来。

如果对于这种两个分支都有新的提交,主要分两种情况讨论:
master 和 bugfix 新的提交没有文件冲突
执行 git merge bugfix
会出现以下信息,可以修改 merge 的 commit message 信息。
Merge branch 'bugfix'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
~
~
合并两个修改会生成一个提交。这时,master
分支的 HEAD 会移动到该提交上。新的合并节点 E 的 commit message 是“Merge branch 'bugfix'”,加不加 --ff
的效果其实是一样的。
