git:rebase的原理
git:rebase的原理
前提:
- 在最近的项目中,我碰到这样一个情况:第一版app上线之后,团队紧接着进行第二版本的开发,由于团队成员对git使用不熟悉,所以开发的每一次提交都是往远端master分支上提交。
- 第一版本打包上线之后,我想让后续的开发中master分支保持代码高可用性,于是在远端建立新的分支
second_version用于第二版本的开发,到时候再合并到master分支上,奈何有的团队成员不会提交远程其他分支,导致master被污染(如下图)

由于团队成员对git的熟练程度不同,有的使用可视化工具提交,有的使用命令行(比如我),当使用merge的时候会出现如上图所示的问题,点线图错综复杂,原因是在merge时会将本地的提交与拉取的提交融合成新的提交,也就是如图所示的Merge remote-tracking branch...,并且会将所有的提交显示在点线图上,十分混乱。但是使用rebase的时候,点线图则会很优雅:

点线图是一条直线。网上有很多关于rebase和merge的区别解释,以下分享的是我自己对rebase的观点,希望可以帮助大家理解。
rebase原理
首先大家在开发过程中肯定会经常碰到这样的情况:当你执行git push时出现错误信息:

这是因为跟你当前分支相关联的远端分支上已经有别人提交了新的代码,或者说你想push的commit的基点已经变更(后面会说明什么是基点)。
问题引出:这里涉及到本地分支与远端分支关联的问题,使用
git branch -vv查看关联关系:
本地master默认与origin/master相关联,当你执行git push或git push origin master时,其完整命令是git push origin master:master,前一个master是你本地的master,后一个master是远端master。所以如果没有特别指定,无论你在本地的哪个分支,git push命令都只会将你本地master分支上的代码进行提交。当你在本地新建其他分支git checkout -b test,默认是不会与远程分支相关联的。所以当你在该分支上进行git push时会有如下问题出现

根据提示,使用git push --set-upstream origin test可以与远端分支test进行关联,这里的test要换成自己的分支名。
回到正题
rebase,故名思意re-base,重新定义基点,当你的代码push不上去的时候,你可以使用git pull -r或是git pull --rebase拉取并合并远端分支,然后执行git status查看是否出现冲突,以下是冲突情况:

红框字的翻译大致是:以'1f618a1'为基点重新定义分支master。1f618a1可以看作是每一次提交的唯一标识码。
我将以下图来讲述rebase的原理:

不同的字母分别代表不同的提交,图中从左到右分别以时间从小到大进行排列。每个commit都以前一个commit作为基点进行开发,例如D是以C为基点进行开发。当我开发完D后,准备push到远端master时,git会进行检查:远端master的最新节点是否是节点D的基点,即检查远端master的基点是否是节点C,如果是,则可以直接push,如果不是,也就是上图的情况:在你push之前远端master已经被他人提交了E和F节点,这时可以执行git pull -r

git会以F节点作为新的基点,与D节点的代码进行融合,如果此时出现冲突,那么你就会被移到临时解冲突的分支,需要人工解冲突,解完后执行git add -A保存操作,再执行git rebase --continue继续后续操作,你可能会遗漏某一处冲突,这个完全不同担心,git rebase --continue会帮你检查是否解决完成,如果没有完成则不会让你回到正常分支。
下图是冲突解决完且顺利执行git rebase --continue的情况:

可以看到,此时我再执行git push,就可以顺利将D节点提交到远端master上去了:

可以看到,远端master保持了一条直线,让人看起来非常舒服,这就是rebase的好处,而不像文章开头使用merge那样杂乱、让人迷惑。
git:rebase的原理的更多相关文章
- 使用git Rebase让历史变得清晰
当多人协作开发一个分支时,历史记录通常如下方左图所示,比较凌乱.如果希望能像右图那样呈线性提交,就需要学习git rebase的用法. “Merge branch”提交的产生 我们的工作流程是:修改代 ...
- 你真的懂git rebase吗?
前段时间由于某种原因,开始接手开发公司前端Vue搭建的项目 该前端项目采用的是基于git rebase的形式去合并代码,而我之前使用git一直都是采用merge的形式合并分支代码,对于rebase一概 ...
- Git应用详解第九讲:Git cherry-pick与Git rebase
前言 前情提要:Git应用详解第八讲:Git标签.别名与Git gc 这一节主要介绍git cherry-pick与git rebase的原理及使用. 一.Git cherry-pick Git ch ...
- 聊下 git rebase -i
在使用git作为源代码管理工具的时候,开发的时经常会面临一个常见的问题,多个commit 需要合并为一个完整的commit提交. 在一个基本的迭代周期里,你会有很多次commit,有跟配置文件相关的, ...
- [git]rebase和merge
转自:http://blog.csdn.net/wh_19910525/article/details/7554489 Git merge是用来合并两个分支的. git merge b # 将b分支合 ...
- git merge 和 git rebase 小结
Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 ---------------------- ...
- Git merge 与 git rebase的区别
Git merge的用法: git merge Dev // Dev表示某分支,表示在当前分支合并Dev分支 git merge -m "Merge from Dev" Dev ...
- git知识总结-2.git基本操作之原理说明
0.前言 本文主要对git常用命令的工作原理做一个详细的说明,常用命令主要包括: 1.git add git add相关命令很简单,主要实现将工作区修改的内容提交到暂存区,交由git管理. 2. gi ...
- git rebase 的使用
rebase 在 Git 中整合来自不同分支的修改主要有两种方法:merge 以及 rebase. 在本节中我们将学习什么是“rebase”,怎样使用“rebase”,并将展示该操作的惊艳之处,以及指 ...
随机推荐
- js递归遍历树结构(tree)
如图: 代码: let datas = [] //是一个树结构的数据 setName(datas){ //遍历树 获取id数组 for(var i in datas){ this.expandedKe ...
- -Bash: Unzip: Command Not Found解决方法 安装unzip
利用unzip命令解压缩的时候,出现-bash: unzip: command not found的错误. unzip——命令没有找到,其原因肯定是没有安装unzip.利用一句命令就可以解决了. 命令 ...
- Codeforces Round #180 (Div. 1 + Div. 2)
A. Snow Footprints 如果只有L或者只有R,那么起点和终点都在边界上,否则在两者的边界. B. Sail 每次根据移动后的曼哈顿距离来判断是否移动. C. Parity Game 如果 ...
- 2018-10-19-jekyll-添加-Valine-评论
title author date CreateTime categories jekyll 添加 Valine 评论 lindexi 2018-10-19 09:10:40 +0800 2018-2 ...
- Error与Exception的区别,Java常见异常Execption总结
错误和异常的区别(Error vs Exception) 错误和异常的区别(Error vs Exception) 今天面试问了这样一个问题,"Error" 和 "Exc ...
- gulp4.0基本配置,超简单!
最近复习了一下gulp,目前是4.0版本. 下图是基本目录结构,文件里面的内容可以随意添加,超详细简洁啊! 直接上代码(依赖未完全使用): 项目的所有依赖都可以安装,每个都有详细的注释. const ...
- C# 多线程的等待所有线程结束
//前台线程和后台线程唯一区别就是:应用程序必须运行完所有的前台线程才可以退出://而对于后台线程,应用程序则可以不考虑其是否已经运行完毕而直接退出,//所有的后台线程在应用程序退出时都会自动结束 ...
- Linux 内核控制 urb
控制 urb 被初始化几乎和 块 urb 相同的方式, 使用对函数 usb_fill_control_urb 的 调用: void usb_fill_control_urb(struct urb *u ...
- HDU - 3530 Subsequence (单调队列)
Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- 洛谷——P1160 队列安排(链表的基础操作)
#include<bits/stdc++.h> using namespace std; ]; list<int> stus; list<];//用来存放每一项的迭代器 ...