如何理解git rebase?

2018-10-12 admin

clipboard.png

在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

其次,它会应用我们想集成的来自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

Merge Option

git checkout feature
git merge master
git merge master feature

会有一个’merge commit’, 但是merge是非常安全的,不会像rebase有很多陷阱。 但是若master非常活跃,每次merge都会有要给’merge commit’,会导致feature的commit history很脏。 image

Rebase Option

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

image

  • 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

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

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

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

image 相当于:

git checkout feature
git rebase master

像下图这样: image

image

原文链接:https://segmentfault.com/a/1190000016663409

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-42536.html

文章标题:如何理解git rebase?

相关文章
如何优雅的使用vue+Dcloud(Hbuild)开发混合app
最近在做混合app,前端框架用的是vue,打包app使用的是Dcloud,不过在开发过程中有一点不爽的是,如果想使用Dcloud提供的plus这个环境变量,难倒每次都得使用npm run build先把vue打包,然后再用Hbuild打开...
2018-05-22
深入理解JavaScript的React框架的原理
如果你在两个月前问我对React的看法,我很可能这样说: 我的模板在哪里?javascript中的HTML在做些什么疯狂的事情?JSX开起来非常奇怪!快向它开火,消灭它吧! 那是因为我没有理解它. 我发誓,React 无疑是在正确的轨道...
2017-03-26
WebStorm操作Git
前期配置 ① 确定git已经安装后,打开webstorm,在file-settings中直接搜索github,然后输入自己github的账号密码 ② 点击test,出现onnection successful的提示框,说明连接到github...
2018-04-18
关于js里的this关键字的理解
this关键字在c++,java中都提供了这个关键字,在刚开始学习时觉得有难度,但是只要理解了,用起来就方便多了,下面通过本篇文章给大家详解js里this关键字的理解。 关于this,是很多前端面试必考的题目,有时候在网上看到这些题目,自己...
2017-03-29
深入理解JavaScript编程中的原型概念
JavaScript 的原型对象总是让人纠结。即使是经验丰富的JavaScript专家甚至其作者,经常对这一概念给出很有限的解释。我相信问题来自于我们对原型最早的认识。原型总是与new, constructor 以及令人困惑的prototy...
2017-03-25
ajax如何实现页面局部跳转与结果返回
通过代码示例分析给大家介绍ajax实现页面局部跳转与结果返回,具体内容如下: 1、带有结果返回的提交过程 这里用一个提交按钮来演示,HTML代码为: <input type="button" class=&quot...
2017-03-29
JavaScript 闭包深入理解(closure)
一、什么是闭包? “官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。 相信很少有人能直接看懂这句话,因为他描述的太学术。其实这句话通俗的来说就是:JavaScript...
2017-03-23
js如何实现点击标签文字,文字在文本框出现
js实现点击标签文字,文字出现在文本框里,下面2种方法实现的功能略有不同,总体来说方法一功能更强大。 第一种方法:随意点击任何标签都会出现在文本框中,如何第二次点击标签,对应的文字就会在文本框中消失。 <style>.c{ wi...
2017-03-29
javascript如何操作HTML下拉列表标签
先给大家讲下大概实现思路,具体内容介绍请看下面。 判断select选项中 是否存在Value="paraValue"的Item 向select选项中 加入一个Item 从select选项中 删除一个Item 删除sele...
2017-03-29
JavaScript如何自定义trim方法
相比vbscript,javascript在字符串处理方面已经很强大了,但是偏偏缺少去除字符串前后空格的trim方法。 //clear the right and left space function trim(s){...
2017-03-27
回到顶部