GIT学习笔记(5):变基
GIT学习笔记(5):变基rebase
变基
引入变基
在Git中整合来自不同分支的修改主要有两种方法:merge以及rebase。
整合分支最容易的方法是merge,他会把两个分支的最新快照以及两者最近的共同祖先进行三分合并,合并的结果是生成一个新的快照(并提交)。如下图所示:

其实,还有一种方法,我们可以提取在TESTING在COMMIT:vg65w上所做的修改,然后根据它在MASTER所在的COMMIT:gta24上重新做一遍,就像重新播放一样,这样提交到某一分支上的所有修改都已到了另一分支上,我们称这种操作为变基。
它的原理是这样的,首先找到这两个分支(即当前分支TESTING,以及目标基底分支MASTER)的最近共同祖先,然后对比当前分支(TESTING)相对于该祖先的历次提交,提取相应的修改保存为临时文件,然后以基底分支(MASTER)的最后一个提交对象(橙黄色)为新的出发点,逐个应用之前准备好的临时文件,最后会生成一个新的合并提交对象(红色),从而改写TESTING的提交历史,使它成为MASTER的直接下游。
最后回到master,执行一次快速合并。

在Git中我们需要使用rebase命令来完成这样的操作。

同样,我们在合并的过程中也遇到了冲突,这时我们需要,找到冲突文件,如上所述Test.java,进行冲突处理.

处理完冲突以后,我们需要将冲突文件添加到暂存区,同时执行git rebase --continue命令执行后续的变基操作,最后回到master,执行一次快速合并操作即可。

说明:可以使用git rebase --abort命令来取消当前的变基操作。
为什么变基
虽然最后整合得到的结果没有任何区别,但变基能产生一个更为整洁的提交历史。如果视察一个变基过的分支的历史记录,看起来会更清楚:仿佛所有修改都是在一根线上先后进行的,尽管实际上它们原本是同时并行发生的。
一般我们使用变基的目的,是想要得到一个能在远程分支上干净应用的补丁——比如某些项目你不是维护者,但是相帮点忙,最好用变基:
先在你自己的一个分支中进行开发,当准备向主项目提交补丁的时候,根据最新的origin/master进行一次变基操作然后再提交,这样维护者就不需要做任何整合工作(实际上是把解决分支补丁同最新主干代码之间冲突的责任,化转为由提交补丁的人来解决),只需要根据你提供的仓库地址做一次快速合并,或者直接采纳你提交的补丁。
请注意,合并结果中最后一次提交所指向的快照,无论是通过变基,还是三方合并,都会得到相同的快照内容,只不过提交历史不同罢了。变基是按照每行的修改次序重演一遍修改,而合并是把最终结果合在一起。
指定分支进行变基
变基也可以放到其他分支进行,并不一定非得根据分化之前的分支。在对两个分支进行变基时,所生成的“重放”并不一定要在目标分支上应用,你也可以指定另外的一个分支进行应用。

假设你希望将 client 中的修改合并到主分支并发布,但暂时并不想合并 server 中的修改,因为它们还需要经过更全面的测试。 这时,你就可以使用 git rebase 命令的 --onto 选项,选中在 client 分支里但不在 server 分支里的修改(即 C8 和 C9,没有C3,是因为C3存在于server分支里),将它们在 master 分支上重放:
$ git rebase --onto master server client
以上命令的意思是:“取出 client 分支,找出处于 client 分支和 server 分支的共同祖先之后的修改,然后把它们在 master 分支上重放一遍”。 这理解起来有一点复杂,不过效果非常酷。

现在可以快进合并 master 分支了

接下来你决定将 server 分支中的修改也整合进来。 使用 git rebase [basebranch] [topicbranch] 命令可以直接将特性分支(即本例中的 server)变基到目标分支(即 master)上。这样做能省去你先切换到 server 分支,再对其执行变基命令的多个步骤。
$ git rebase master server

最后进行快速合并,然后删除client分支和server分支,形成了一条清晰的提交历史

变基的风险
在变基的时候,我们要遵循一条准则:
一旦分支中的提交的对象发布到公共仓库,就千万不要对该分支进行变基操作。
如果你遵循这条金科玉律,就不会出错错,否则要向全国人民谢罪!
在进行变基的时候,实际上抛弃了一些现存的提交对象而创造了一些类似但不同的新的提交对象。如果你把原来分支中的提交对象发布出去,并且其他人更新下载后在其基础上开展工作,而稍后你又用 git rebase 抛弃这些提交对象,把新的重演后的提交对象发布出去的话,你的合作者就不得不重新合并他们的工作,这样当你再次从他们那里获取内容时,提交历史就会变得一团糟。
参考资料
《GIT官方文档》
GIT学习笔记(5):变基的更多相关文章
- Git学习笔记与IntelliJ IDEA整合
Git学习笔记与IntelliJ IDEA整合 一.Git学习笔记(基于Github) 1.安装和配置Git 下载地址:http://git-scm.com/downloads Git简要使用说明:h ...
- Git学习笔记(10)——搭建Git服务器
本文主要记录了Git服务器的搭建,以及一些其他的配置,和最后的小总结. Git远程仓库服务器 其实远程仓库和本地仓库没啥不同,远程仓库只是每天24小时开机为大家服务,所以叫做服务器.我们完全可以把自己 ...
- Git学习笔记(四)
一.忽略特殊文件 在Git工作区的根目录下创建一个特殊的.gitignore文件,然后把要忽略的文件名填进去,Git就会自动忽略这些文件. 不需要从头写.gitignore文件,GitHub已经为我们 ...
- git 学习笔记6--remote & log
git 学习笔记6--remote & log 创建SSH Keys ssh-keygen -t rsa -C "1050244110@qq.com" 本地关联远程 git ...
- Git学习笔记---协作的一般流程
一般的操作流程 1.pull 王小坤与另一个同事张大炮一起开发一个项目,张大炮昨天修改了数据库读写的api,优化了执行速度,并把read()函数改名成了Read(),下午下班之前把这些代码push到服 ...
- 【转帖】Git学习笔记 记录一下
本文内容参考了廖雪峰老师的博文,并做了适当整理,方便大家查阅. 原帖地址 https://wangfanggang.com/Git/git/ 常用命令 仓库初始化 - git init 1 git i ...
- [转]Git学习笔记与IntelliJ IDEA整合
Git学习笔记与IntelliJ IDEA整合 一.Git学习笔记(基于Github) 1.安装和配置Git 下载地址:http://git-scm.com/downloads Git简要使用说明:h ...
- GIT学习笔记(1):创建版本库
GIT学习笔记(1):创建版本库 创建版本库 1.创建合适目录并初始化为仓库 版本库即需要交由Git进行版本控制的目录,其下所有文件的修改.删除,Git都能跟踪还原. 说明:初始化后,当前目录下会多出 ...
- GIT学习笔记(4):远程分支
GIT学习笔记(4):远程分支 远程分支 远程分支是什么 远程分支是对远程仓库中的分支的索引.它们是一些无法移动的本地分支:只有在GIT进行网络交互时才会更新.远程分支就是书签,提醒着你上次连接远程仓 ...
随机推荐
- 如何 “解决” WPF中空域问题(Airspace issuse)
空域问题是由于Winform与WPF在底层渲染机制上有所区别而导致的.多数情况下,开发者为了实现不规则的窗体并承载Winform控件时,遇到此类问题.当WPF窗体设置为允许透明(也就是AllowsTr ...
- .net 编译原理
这听起来像是个非常高大上的名字,上学的时候我们学过的编译原理或者编译技术实际上是在讲如何将高级程序语言如C++编译为计算机可以理解的汇编语言,这里说的编译原理只是想说明在.NET的世界里编译这件事儿和 ...
- 【转】不用程序mysql也可以查询今天、昨天、7天、近30天、本月、上一月的数据
今天 select * from 表名 where to_days(时间字段名) = to_days(now()); 昨天 SELECT * FROM 表名 WHERE TO_DAYS( NO ...
- JavaScript如何定义数组。
JavaScript如何定义数组. 解答: var arrTest=new Array();
- XHTML XML
XHTML是可扩展的超文本标记语言(Extensible HyperText Markup Language). l XHTML是w3c组织在2000年的时候为了增强HTML推出的,本来是想替代HT ...
- (转)数据库ACID特性
转自:http://blog.csdn.net/shuaihj/article/details/14163713 隔离级别实现原理:http://www.cnblogs.com/wrencai/p/5 ...
- 2015InfoQ软件大会技术记录
前述 参加infoq软件大会,最大的感触就是,互联网行业的技术发展日新月异:由市场痛点.用户痛点.开发痛点所驱动的技术变革更是遍地开花.新的技术新的思维也是层出不穷:大会中频频提到的高扩展高可用架构. ...
- python3----模块(序列化(json&pickle)+XML+requests)
一.序列化模块 Python中用于序列化的两个模块: json 跨平台跨语言的数据传输格式,用于[字符串]和 [python基本数据类型] 间进行转换 pickle python内置的数据 ...
- iOS -转载-字符串是否为空判断方法
- (BOOL)blankString{ if (![self isKindOfClass:[NSString class]] ){ return YES; } if ([self isEqual:[ ...
- Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded.
EF6进行Insert操作的时候提示错误 Store update, insert, or delete statement affected an unexpected number of rows ...