git pull --rebase 和 git pull 的区别

转载:http://hungyuhei.github.io/2012/08/07/better-git-commit-graph-using-pull---rebase-and-merge---no-ff.html

pull --rebase

首先是吐嘈

如果你正在 code review,看到上图(下文将称之为:提交线图)之后,特别是像我这样有某种洁癖的人,是否感觉特别难受?如果是的话,请看下文吧 :)

为什么

Git 作为分布式版本控制系统,所有修改操作都是基于本地的,在团队协作过程中,假设你和你的同伴在本地中分别有各自的新提交,而你的同伴先于你 push 了代码到远程分支上,所以你必须先执行 git pull 来获取同伴的提交,然后才能 push 自己的提交到远程分支。而按照 Git 的默认策略,如果远程分支和本地分支之间的提交线图有分叉的话(即不是 fast-forwarded),Git 会执行一次 merge 操作,因此产生一次没意义的提交记录,从而造成了像上图那样的混乱。

解决

其实在 pull 操作的时候,,使用 git pull --rebase 选项即可很好地解决上述问题。 加上 --rebase 参数的作用是,提交线图有分叉的话,Git 会 rebase 策略来代替默认的 merge 策略。 使用 rebase 策略有什么好处呢?借用一下 man git-merge 中的图就可以很好地说明清楚了。

假设提交线图在执行 pull 前是这样的:

                 A---B---C  remotes/origin/master
                /
           D---E---F---G  master

如果是执行 git pull 后,提交线图会变成这样:

                 A---B---C remotes/origin/master
                /                    D---E---F---G---H master

结果多出了 H 这个没必要的提交记录。如果是执行 git pull --rebase 的话,提交线图就会变成这样:

                       remotes/origin/master
                           |
           D---E---A---B---C---F‘---G‘  master

F G 两个提交通过 rebase 方式重新拼接在 C 之后,多余的分叉去掉了,目的达到。

小结

大多数时候,使用 git pull --rebase 是为了使提交线图更好看,从而方便 code review。

不过,如果你对使用 git 还不是十分熟练的话,我的建议是 git pull --rebase 多练习几次之后再使用,因为 rebase 在 git 中,算得上是『危险行为』

另外,还需注意的是,使用 git pull --rebase 比直接 pull 容易导致冲突的产生,如果预期冲突比较多的话,建议还是直接 pull。

merge --no-ff

上述的 git pull --rebase 策略目的是修整提交线图,使其形成一条直线,而即将要用到的git merge --no-ff <branch-name> 策略偏偏是反行其道,刻意地弄出提交线图分叉出来。

假设你在本地准备合并两个分支,而刚好这两个分支是 fast-forwarded 的,那么直接合并后你得到一个直线的提交线图,当然这样没什么坏处,但如果你想更清晰地告诉你同伴:这一系列的提交都是为了实现同一个目的,那么你可以刻意地将这次提交内容弄成一次提交线图分叉。

执行 git merge --no-ff <branch-name> 的结果大概会是这样的:

中间的分叉线路图很清晰的显示这些提交都是为了实现 complete adjusting user domains and tags

更进一步

往往我的习惯是,在合并分支之前(假设要在本地将 feature 分支合并到 dev 分支),会先检查 feature 分支是否『部分落后』于远程 dev 分支

git checkout dev
git pull # 更新 dev 分支
git log feature..dev

如果没有输出任何提交信息的话,即表示 feature 对于 dev 分支是 up-to-date 的。如果有输出的话而马上执行了 git merge --no-ff 的话,提交线图会变成这样:

所以这时在合并前,通常我会先执行:

git checkout feature
git rebase dev

这样就可以将 feature 重新拼接到更新了的 dev 之后,然后就可以合并了,最终得到一个干净舒服的提交线图。

再次提醒:像之前提到的,rebase 是『危险行为』,建议你足够熟悉 git 时才这么做,否则的话是得不偿失啊。

总结

使用 git pull --rebase 和 git merge --no-ff 其实和直接使用 git pull git merge 得到的代码应该是一样。

使用 git pull --rebase 主要是为是将提交约线图平坦化,而 git merge --no-ff 则是刻意制造分叉。

一言以蔽之:如果你有点洁癖症状,才考虑用它们吧。

时间: 2024-08-02 15:59:04

git pull --rebase 和 git pull 的区别的相关文章

Git----拉取远程分支,git pull,git rebase,git pull --rebase的区别

git pull 相当于自动的 fetch 和 merge 操作,会试图自动将远程库合并入本地库,在有冲突时再要求手动合并. git rebase 可以确保生产分支commit是一个线性结构,方便rollback.其实生产也可以选择打tag来发布. 注:通过rebase可以确保主分支commit history线性结构上每个commit点都是相对独立完整的功能单元.除了美感,这样做也有助于团队间的分工协作,比随便merge效果好. git pull --rebase(推荐用这个) 把本地 rep

对比git pull和git pull --rebase

1.使用下面的关系区别这两个操作:git pull = git fetch + git mergegit pull --rebase = git fetch + git rebase 2 一.基本 git rebase用于把一个分支的修改合并到当前分支. 假设你现在基于远程分支"origin",创建一个叫"mywork"的分支. $ git checkout -b mywork origin 假设远程分支"origin"已经有了2个提交,如图 现

git fetch 、git pull 与 git pull --rebase

1. git fetch 与 git pull 都是从远程拉取代码到本地,git fetch只是拉取到本地,git pull不仅拉取到本地还merge到本地分支中.所以git pull是git fetch与git merge的集合体.  2. git pull 与 git pull --rebase git pull的默认行为是git fetch + git merge,  git pull --rebase则是git fetch + git rebase. 从目的来说,两者没差别,运行之后,

聊下git pull --rebase

有一种场景是经常发生的. 大家都基于develop拉出分支进行并行开发,这里的分支可能是多到数十个.然后彼此在进行自己的逻辑编写,时间可能需要几天或者几周.在这期间你可能需要时不时的需要pull下远程develop分支上的同事的提交.这是个好的习惯,这样下去就可以避免你在一个无用的代码上进行长期的开发,回头来看这些代码不是新的代码.甚至是会面临很多冲突需要解决,而这个时候你可能还需要对冲突的部分代码进行测试回归,这就很麻烦了. 那么我们来看一下你在pull时候需要习惯性的加上-rebase参数,

【git之】fetch和 pull的区别

Git中从远程的分支获取最新的版本到本地有这样2个命令:1. git fetch:相当于是从远程获取最新版本到本地,不会自动merge Git fetch origin master git log -p master..origin/master git merge origin/master 以上命令的含义:   首先从远程的origin的master主分支下载最新的版本到origin/master分支上   然后比较本地的master分支和origin/master分支的差别   最后进行

Git 代码更新:git fetch 和 git pull 的区别

Git 从远程的分支获取最新的版本到本地有这样 2 个命令: 1. git fetch:相当于是从远程获取最新版本到本地,但不会自动 merge git fetch origin master git log -p master origin/master git merge origin/master 以上命令的含义: 首先从远程的 origin 的 master 主分支下载最新的版本到 origin/master 分支上 然后比较本地的 master 分支和 origin/master 分支

git merge rebase的区别及应用场景

前两天和同事交流发现他在日常开发中跟上游保持同步每次都是用git pull操作,而我一直习惯git fetch然后rebase,发现这两种操作后的log是有些区别的.他每次pull操作之后都会自动生成一个merge记录,而使用fetch+rebase就没有. 查了下发现其实就是git pull命令两种参数的区别: git pull --merge  默认参数,相当于:git fetch + git merge git pull --rebase 手动指定,相当于:git fetch + git

Git: 聊聊Rebase命令,与Merge的区别

转帖自2015-12-02 lazybios 日拱一卒 相比Merge命令,大家对Rebase要相对陌生一些,Rebase这个命令在<Pro Git book>中被翻译为「衍合」,感觉好别扭,个人感觉无论是从音还是行(为)叫做「变基」要更佳恰当一些. Rebase的大致流程 Step1: 场景假定 你基于一个远程分支origin创建了一个mywork的分支 git checkout -b mywork origin Step2: 进行开发 创建好分支后,你就开始兢兢业业的在mywork分支上开

好代码是管出来的——Git的分支工作流与Pull Request

上一篇文章介绍了常用的版本控制工具以及git的基本用法,从基本用法来看git与其它的版本控制工具好像区别不大,都是对代码新增.提交进行管理,可以查看提交历史.代码差异等功能.但实际上git有一个重量级的功能“分支”,git的分支与其它工具的分支不同,git分支的操作完全在本地进行,所以可以快速的创建和切换. 版本控制工具除了对代码进行管理外,实际上它还影响了整个软件编码的工作流程,git因为其分支特性使得开发流程发生了变化,本文将从以下几点来介绍分支和git的工作流程: 版本控制管理分支简介 G