git merge 和git rebase区别
2017-05-11 09:52
239 查看
前言
相信大部分使用 Git 的朋友都会遇见相同的疑问,并且也从网上搜索了不少资料。那么,为什么我还要写这篇文章呢?因为我想尝试从自己的角度解释这个问题,如果能给到大家灵光一闪的感悟,便善莫大焉啦。估计点进来的朋友也对 merge 和 rebase 有了一定了解,所以我也就不浪费篇幅再去详细介绍 merge 和 rebase,让我们直入主题吧。
merge 与 rebase 的区别
merge
现在假设我们有一个主分支 master 及一个开发分支 deve,仓库历史就像这样:初始仓库历史
现在如果在 master 分支上
git merge deve:Git 会自动根据两个分支的共同祖先即
e381a81这个
commit 和两个分支的最新提交即
8ab7cff和
696398a进行一个三方合并,然后将合并中修改的内容生成一个新的
commit,即下图的
78941cb
merge 合并图
rebase
rebase 是什么情况呢?还是一个初始的仓库历史图:rebase初始仓库历史
如果是在 master 分支上
git rebase deve:Git 会从两个分支的共同祖先
3311ba0开始提取
master 分支(当前所在分支)上的修改,即
85841be、
a016f64与
e53ec51,再将
master 分支指向 deve 的最新提交(目标分支)即
35b6708处,然后将刚刚提取的修改依次应用到这个最新提交后面。操作会舍弃
master 分支上提取的 commit,同时不会像 merge 一样生成一个合并修改内容的 commit,相当于把 master 分支(当前所在分支)上的修改在 deve 分支(目标分支)上原样复制了一遍,操作完成后的版本历史就像这样:
rebase 合并图
可以看见 master 分支从 deve 分支最新提交
35b6708开始依次提交了自己的三个 commit(由于是提取修改后重新依次提交,故
commit 的 hash 码与上面的
85841be、
a016f64、
e53ec51不同)
rebase -i
rebase 操作加上 -i选项可以更直观的看见被提取的 commit 信息。
仍然在 master 分支上 rebase deve 分支,不过这次要加上
-i选项,即
git rebase -i deve,然后我们可以得到这样一个文本信息框
rebase -i信息
A 区域内的信息说明了这次 rebase 操作提取了哪些 commit 记录(
f9a7673与
edb2ba2),会连接到目标分支的哪个
commit (
9c86a5c)后面。可以根据 B 区域中的命令说明修改
pick为其他命令,对该次提取出来的
commit 做额外的操作
B 区域内说明了本次 rebase 操作可以选用的命令
通过
:wq保存退出后,就会按照刚刚在
A 区域内设定的命令处理 commit 并 rebase。
冲突处理策略的不同
merge 遇见冲突后会直接停止,等待手动解决冲突并重新提交 commit 后,才能再次 mergerebase 遇见冲突后会暂停当前操作,开发者可以选择手动解决冲突,然后
git rebase --continue继续,或者
--skip跳过(注意此操作中当前分支的修改会直接覆盖目标分支的冲突部分),亦或者
--abort直接停止该次
rebase 操作
merge --no-ff
与 merge
--ff-only
的区别
上面对 merge 的讲述都是基于其默认操作即 --no-ff(
git merge xxx=
git merge --no-ff xxx)的说明,但是 merge
还有一种常用的选项
--ff-only,那么这两种有什么区别呢?
--no-ff是 merge 的默认操作,三方合并并提交修改;而
--ff-only会判断当前分支可否根据目标分支快速合并,就像下面这样
快速合并
此时 deve 分支就可与 master 分支快速合并。
在 deve 分支上
git merge --ff-only master,便得到合并完成后的版本历史图
快速合并完成
可以发现
--ff-only生成的历史记录和 rebase 十分相似,但是本质上
--ff-only仍然是合并操作,但
rebase 并没有做合并,仅仅是提取修改到目标分支后面。
总结:选择 merge 还是 rebase?
merge 是一个合并操作,会将两个分支的修改合并在一起,默认操作的情况下会提交合并中修改的内容merge 的提交历史忠实地记录了实际发生过什么,关注点在真实的提交历史上面
rebase 并没有进行合并操作,只是提取了当前分支的修改,将其复制在了目标分支的最新提交后面
rebase 的提交历史反映了项目过程中发生了什么,关注点在开发过程上面
merge 与 rebase 都是非常强大的分支整合命令,没有优劣之分,使用哪一个应由项目和团队的开发需求决定
merge 和 rebase 还有很多强大的选项,可以使用
git help <command>查看
最后:一些注意点
使用 merge 时应考虑是采用 --no-ff默认操作,生成一个对回顾提交历史并不友好的合并记录,还是采用
--ff-only方式
rebase 操作会丢弃当前分支已提交的 commit,故不要在已经 push 到远程,和其他人正在协作开发的分支上执行 rebase 操作
与远程仓库同步时,使用 pull 命令默认进行了
git fetch + git merge --no-ff两个操作,可以通过加上
--rebase命令将
fetch 后的 merge 操作改为 rebase 操作,或者仅仅 'git fetch remoteName',然后才思考采取哪种整合策略
git merge(or rebase) origin/master
开发与 commit 时注意自己此时在哪个分支上
当有修改未 commit 时,不能进行 rebase 操作,此时可以考虑先用
git stash命令暂存
【转载】http://www.jianshu.com/p/c17472d704a0
相关文章推荐
- git merge与rebase 区别
- git merge和rebase的区别
- git merge和git rebase的区别
- Git rebase、merge 区别
- git merge和rebase的区别
- git merge和rebase的区别
- git merge 和 git rebase 区别
- [git]merge和rebase的区别
- git merge和rebase的区别
- git merge和git rebase的区别
- git fetch 后, git merge 和 git rebase的区别
- Git中分支merge和rebase的适用场景及区别
- git命令Merge和Rebase的区别
- git merge 与 rebase 的区别
- Eclipse上GIT插件EGIT使用手册之九_Rebase和Merge的区别
- Eclipse上GIT插件EGIT使用手册之九_Rebase和Merge的区别
- Eclipse上GIT插件EGIT--_Rebase和Merge的区别
- git rebase与git merge区别
- git merge和git rebase的区别
- [git]merge和rebase的区别