如何使用Git Rebase

我们在日常开发中使用 Git 做分支合并的时候有两种方式:merge 和 rebase。merge 是最常用的,rebase 使用的没有 merge 这么多,那么 rebase 和 merge 有什么区别呢?什么时候使用 rebase?使用 rebase 的时候有什么注意事项呢?接下来我来看下这三个问题。

基础

首先我们先了解下 merge 和 rebase 的运行机制有什么不同。假设我们有两个分支(master 和 feature)。feature 是基于 master 的 C1 节点建立的分支,然后开发人员分别在两个分支各自开发:

rebase图1.png

merge

现在我们想要把 feature 分支开发的内容合并到 master,使用 merge 命令:

$ git checkout master
$ git merge feature
rebase图2.png

Git 会把 C2 和 C3 的内容合并一下产生一个新的修改 C4,把 C4 提交到 master 分支。那么 master 就有了所有最新的代码(红色是 master 分支线,蓝色是 feature 分支线)。

rebase

我们回到还是未合并之前的状态,看看使用 rebase 合并会有什么效果。使用 rebase 有两种用法,先看第一种:

$ git checkout master
$ git rebase feature
rebase图3.png

Git 把 C2 备份成 C2',删除 C2,然后把 C2' 追加到 C3 后面,把 master 指向 C2'。看图上红线,成为了新的 master,这条线上同样有所有的最新代码,起到的作用也是合并了两个分支。那么和 merge 有什么区别呢?就是历史时间线的区别。merge 保留了你所有的操作记录,而 rebase 把提交的修改节点变成了线性的时间线。如果分支 merge 很多的话,时间线会错综复杂,这个时候 rebase 的好处就出现了,对人肉追溯比较友好。

我们再看下合并两个分支 rebase 的第二种用法:

$ git checkout feature
$ git rebase master
$ git checkout master
$ git merge feature
rebase图4.png

前两条命令我们先在 feature 上 rebase on master,产生的效果和第一种方法类似,只是把 feature 分支的改动追加到了 master 分支后面(红色是 master 分支线,蓝色是 feature 分支线)。

rebase图5.png

后两条命令是把 feature 分支 merge 到 master 分支。由于 Git 发现不需要合并代码,只需要移动头指针就可以了,所以快速移动(fast forward)头指针到最前面,master 分支这时就有所有最新代码,同样起到了合并分支的作用。

那么第一种和第二种有什么区别呢?直观的看就是时间线上 C2,C3 顺序的区别,对于我们合并分支最终的意图是没有什么区别的。

注意点

如果你是一人开发,且只有本地仓库,那么上面 rebase 用哪种问题都不会太大。但是如果你是多人协作且有远程仓库,那么区别就巨大了。因为你合并完分支之后还需要 push 到远程仓库供别人使用,当你使用第一种方法后,C2 被放到了 C3 后面,你本地的 master 时间线变成了 C1 - C3 - C2',而远程仓库 master 的时间线是 C1 - C2。虽然 C2 和 C2' 是一样的,但是两者时间线历史完全不一样了,Git 认为你这是两个不一样的分支,不允许你 push。这个时候只能用 $ git push --force 强迫提交,用本地的 master 覆盖远程仓库的 master。但是 master 分支别人还在用啊,他们也需要同步 master 分支。但是别人本地的 master 分支并不知道你 rebase 过了远程仓库的 master,所以当他们 pull master 的时候,变成了如下时间线:

rebase图6.png

其他人本地的 master 时间线上会出现两个 C2(C2 和 C2'),然后如果这人把上图的 master 再 push 到远程仓库,会带上上图所有的历史,多来几次以后整个仓库就没有办法看了。而第二种 rebase 的方法是把新的 commit 不断的追加到 master 后面,只要所有人在往 master 上合并代码的时候都遵循第二种方法,那么就不会产生极其混乱的时间线。

什么时候使用

按我们上面看到的,在现实的开发过程中,严格禁止在公共分支上 rebase on 其他分支(譬如不允许在 master 分支上直接运行 git rebase branchname)。使用 merge 是最保险的合并分支方式,如果你对时间线清晰度要求不是那么高的话。但是如果你对时间线的清晰程度有比较高的要求,那么在合并分支的时候按第二种方法 rebase 就能帮助形成清晰的线性时间线,但是 rebase 的坏处是丢失了一部分提交操作历史。

同步分支

除了合并不同分支这种情况,还有一个十分常见的情况,多人在同一个分支上开发,如何保证同一条分支具有清晰的时间线。我们假设有三个人在开发 feature 分支,通常开发习惯是:

  1. checkout feature 分支到本地。
  2. 开发,并把开发的内容提交到本地 feature。
  3. 使用 pull 把远程仓库中的 feature 和本地 feature 同步(pull 的默认方式是把远程的代码和本地代码做 merge 操作)。
  4. push 同步完的 feature 分支到远程仓库。

按上述步骤,我们看下时间线示意图:
先是第1,第2步

rebase图7.png

用户1执行3,4步

rebase图8.png

用户2执行3,4步

rebase图9.png

用户3执行3,4步

rebase图10.png

因为 pull 默认是通过 merge 远程仓库和本地仓库实现同步的,所以每次 pull 都会多出一个提交记录。但是我们可以通过指定参数来指定 pull 的时候使用 rebase 策略$ git pull --rebase。让我们看下每次执行第3步的时候使用 pull rebase 那么会是什么样子。

用户1执行3,4步

rebase图11.png

用户2执行3,4步

rebase图12.png

用户3执行3,4步

rebase图13.png

通过图示我们看到,如果使用 pull 的 rebase 模式,那么多人协作同一个分支也可以做到时间线清晰。最后再通过之前提到的 rebase 方式把 feature 合并到 master 分支上。那么整个开发过程时间线就呈现出清晰的时间线。

总结

  1. 和远程仓库同步当前分支的时候使用 pull --rebase 的方式。
  2. 合并分支的使用 feature rebase on master,master merge feature 的方式。
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,719评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,337评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,887评论 0 324
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,488评论 1 266
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,313评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,284评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,672评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,346评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,644评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,700评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,457评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,316评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,706评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,261评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,648评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,859评论 2 335

推荐阅读更多精彩内容

  • 四、 分支开发工作流 现在你已经学会新建和合并分支,那么你可以或者应该用它来做些什么呢? 在本节,我们会介绍一些常...
    常大鹏阅读 2,069评论 3 24
  • 多种多样的工作流使得在项目中实施Git时变得难以选择。这份教程提供了一个出发点,调查企业团队最常见的Git工作流。...
    JSErik阅读 4,348评论 2 8
  • Git 是目前最流行的分布式版本控制系统之一。 版本控制指的是,记录每次版本变更的内容和时间等细节,保留各版本之间...
    神齐阅读 1,381评论 0 7
  • 开篇之前,我们来说说Git这个东西。至于Git是个什么东西这种问题,我相信不用我说,点开这篇文章的你应该知道的。但...
    点融黑帮阅读 4,338评论 8 66
  • 感恩天地君亲师,感恩祖国的繁荣富强,感恩祖宗培养护佑,感恩生命的力量,又长大了一岁,感恩这一年遇见的每一个人,事,...
    张翔淋阅读 159评论 1 4