如何理解git rebase?

在merge PR的过程中,rebase and merge会产生冲突,因此需要补充一下Git rebase的知识点。

Understanding Rebase (And Merge) in Git

merge 是Git中最简单也是最常用的集成change的方法,但是这并不是唯一的一种方式。
Rebase是另外一种可选的但是略微高级的集成方式。

合并提交的case

通常情况下,一个由人类认真创建的commit,是一个有意义的单元:它仅仅包含相关的change并且每个commit都伴随着一个comment。
有一种merge commit可以让所有comments丢失:Git自动创建的commit,并且由Git填充所有的differ change。没有语义,没有主题。当然,这些独立commits的内容是保留的。但是history分成了注释的,分离的有意义的commit,由于这个原因,在一次merge commit中不会保留。
这就是为什么有些人不喜欢merge,喜欢rebase的原因。

Rebase之美

与一笼统把commits塞到一个commit不同,一个rebase会保留原始的commits。
项目的历史是一条单的,直线。没有任何迹象表明它在某个时候拆分出一个分支来。

image

在一次rebase后,看起来就像development从来没有被拆分成不同的分支。

我们来一步一步拆分一个rebase操作。方案很简单:我们想用rebase集成branch-B到branch-A。


image

一个rebase之前的方案。

命令很简单:

git rebase branch-B

首先,线条开始分支后,Git将"undo"所有的branch-A上的commits(在共同的祖提交后)。当然,它不会丢弃它们,而是临时将它们存了起来。
[图片上传失败...(image-cf01ca-1584858732388)]

其次,它会应用我们想集成的来自branch-B的commits。此使,两个分支是相同的。


image

最后,branch-A的新commits重新被应用,但是在一个新的位置,在branch-B的后面。(they are rebased)。
结果就是development在一条直线上开发。不是一个commit包含了所有的改变,而是让原始commit结构保持原样。


image

下面尝试开BranchA,BranchB两个分支,然后基于webstorm的Version Control,观察git rebase操作会不会有上述的变化。

BranchA


image

BranchB


image

Rebase BranchA onto branchB


image

其实就是将branchB的母分支branchA进行了integrate changes,也就是把branchB的2次commit,放在共同的起点与branchA的新commit之间,或者也可以理解成将branchA的新commit,移动到了branchB的2次commits之后。

rebase的是谁,就修改的是谁
onto的是谁,谁就是被rebase的分支的新commits

其实,rebase只做了一件事:更新base branch!(重点!重点!重点!)

而想将谁的更新内容作为新的base branch的提交,就将作为topicBranch。

非常重要的命令。

git checkout baseBranch
git rebase topicBranch

再说的通俗一点,其实就是:挑了一个branch,把它的特性拿过来,放在我的新特性之前。

Merging vs. Rebasing

看完上面这篇文章后,并没有搞清楚rebase做了什么操作,所以还是需要多读一些文章。

  • 对于初学者来说,git rebase命令就像一个magic voodoo
  • merge和rebase都是用来从一个分支到另一个分支integrate changes的,只是方式不同

[图片上传失败...(image-51ce99-1584858732389)]

Merge Option

git checkout feature
git merge master
git merge master feature

会有一个'merge commit', 但是merge是非常安全的,不会像rebase有很多陷阱。
但是若master非常活跃,每次merge都会有要给'merge commit',会导致feature的commit history很脏。
[图片上传失败...(image-fa201e-1584858732389)]

Rebase Option

git checkout feature
git rebase master
  • feature从master tip处开始合并master上的commits

  • 重写project的history
    [图片上传失败...(image-946390-1584858732389)]

  • rebase后,project的history更加干净了。没了多余的'merge commit',并且成了一条线。

  • rebase 需要遵循Golden Rule of Rebasing,否则会导致灾难性的合作workflow。

  • rebase 会丢失掉merge commit,导致看不到之后合并到feature的commit。

灵活一点的Rebasing

  • 选择特定的commits移动到新分支,加一个i选项
  • fixup某一个提交
git checkout feature
git rebase -i master
pick 33d5b7a Message for commit #1
pick 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3
pick 33d5b7a Message for commit #1
fixup 9480b3d Message for commit #2
pick 5c67e61 Message for commit #3

[图片上传失败...(image-2711fa-1584858732389)]

Golden Rule of Rebasing

永远不要在public 分支上使用git rebase!

image

每次使用git rebase前,问自己"有没有人也正在基于这个branch写代码?"若是的话,就老老实实用merge,不要尝试rebase。
若有gitflow的经验,其实就是当你开了一个feature/foo时,若同事也开了一个feature/bar,而且你们是同时基于develop checkout出来的分支,那么当develop有hotfix merge进去时,若你想拉去最新的develop代码,就不能用git rebase,只能用merge,否则会导致同事的develop分支与我们的develop分支不同,而此时她想再与我们保持同步是很复杂的。

Force-Pushing

若想将rebased的master分支推到远程仓库,Git 将会阻止你,因为它与远程的master分支冲突了。但是,你可以force push。

# 这个命令一定要小心使用
git push --force
  • 只有100%确定自己在做什么时再force,否则会让团队的人很困惑
  • 若是想将某个feature远程分支彻底替换掉,可以这样做。

下面尝试开master,feture两个分支,然后基于webstorm的Version Control,观察git rebase操作会不会有上述的变化。

master


image

feature


image
git checkout feature
git rebase master
# resolve conflict1
git rebase --continue
# resolve confict2
git rebase --continue

Rebase feature onto master


image

webstorm 的 Rebase Current onto selected什么操作?

可以理解成下图这样。

Rebase feature onto master

image

[图片上传失败...(image-aee717-1584858732389)]

Current在WebStorm中指右下角的branch,selected一般指的original branch。

rebase and merge 一个Pull request做了什么操作?

image

相当于:

git checkout feature
git rebase master

像下图这样:
[图片上传失败...(image-512aa-1584858732389)]

image

实际工作中的rebase

一次完整的rebase流程

  1. git checkout feature
  2. git rebase master
  3. resolve conflicts
  4. git add .
  5. git rebase --continue

如果rebase中途出现问题,可以使用git rebase --abort恢复。

git rebase的目的是保持当前feature分支与master主分支同步的另一种方式,虽然与merge的效果相同,但是比merge更加简洁高效。

为什么说rebase比merge更加简洁高效呢?

实际工作中的一个常见场景:在我们的feature开发期间,master上可能发布了很多release,修复了很多hotfix。而且可能刚好影响到了我们目前开发的feature。此时我们需要将feature的代码与master保持同步。

同步有几种方法:自己写一遍;merge;rebase。

  • 自己写一遍
    自己写一遍的方法是最不合理的,因为这会造成conflict,也是一种初学者容易犯的错误。
  • merge
    稍微有经验一点的人,可以选择merge,但是merge以后,我们在自己feature上提交的commit会被湮没在茫茫commit中,很难清晰的从git history中找到,这样我们在开发过程中就很难清晰地知道上一次commit了哪些,最后合并到master上以后,如果出现bug追溯历史commit也很困难。
  • rebase
    最最明智的开发者,会使用rebase的话,解决完冲突之后,就可以将我们feature上的commit全部移动到master的最新commit之后,这样我们在开发过程中,就可以清晰地看到自己在feature上的commit,发布功能之后,也可以按照时间点去review我们的这几次commit,从而快速找到问题。

期待和大家交流,共同进步,欢迎大家加入我创建的与前端开发密切相关的技术讨论小组:

努力成为优秀前端工程师!

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

推荐阅读更多精彩内容