git rebase的时候捅娄子了,怎么办?在线等……
大家在使用git的过程当中有闯过祸吗?
我闯过,我闯的第一个祸就是使用git rebase造成的,虽然后来最终还是解决了,但是还是给我吓得不轻。当时的事情是这样的。
我们来看下这张图:

简单解释一下这张图当中的内容,C1节点是所有分支的最小公共祖先。可以理解成是最早的master版本,之后我们checkout出来了两个分支,分别是bugFix和feature。其中feature是我们新开发的分支,而bugFix是修复bug的分支。
当我们把bugFix了之后就赶紧merge master发布了,当我们发布了之后发现bugFix当中有一点小问题。比如说把不应该提交的文件提交了上来,再加上我们不是用rebase的形式合并的,所以看起来commit记录有一点点乱。于是我决定使用rebase修复一下提交记录,搞完了之后使用git push -f强行更新了远程分支。
因为我们之前已经push过了,想要用新的commit记录覆盖掉旧的就必须要使用-f强行推送。这些操作都是常规的操作,但是我无意之间犯了一个大问题,差点导致了后面的悲剧。
我先卖个关子,大家先用几秒钟时间想一下,这里藏着的问题是什么?
rebase的禁忌
这里藏着的问题就是feature分支,我们从图中可以看到feature分支是merge了C5节点的。但是当我们rebase push -f了之后,C5节点其实就不存在了。我们把图画出来给大家看一下就明白了,这个是rebase之前的依赖树:

我们rebase之后依赖树变成了这样:

由于feature之前曾经merge过master并且依赖了C5节点,而master在rebase强行push之后整个链路当中已经没有C5节点了。也就是说feature分支依赖了一个已经不存在的节点,这个时候还不算太遭,因为feature分支还没有更新,如果feature分支pull一下,那么整个分支会变成这样:

也就是说同样的代码在feature分支当中保存了两个版本,并且如果feature合并进master之后,会发现之前push -f强行抛弃的那些提交又被合并了进来,并且整个commit的log会变得非常非常混乱,难以看懂。
如果这些分支都是自己的,那么自己捏了鼻子也就算了,如果这些分支是团队当中其他人的,那么捅个篓子基本上是避免不了的。如果组里有一个Git大佬知道这种情况该怎么解决还好,否则的话,想要完全复原非常困难,很有可能一通操作完全不知道偏差到哪里去了,也不知道如何找回来。
我当时还好,捅娄子的时候已经学过了这种情况应该怎么处理,虽然还是没能避免踩坑,但好在及时从坑里出来了。在我们来看脱坑的方法之前,先来思考一个问题,对于rebase造成混乱的根源究竟是什么,我们应该怎么避免?
解决rebase的只有rebase
为什么我们刚才在C8节点一旦pull就会导致本地的错乱呢?因为我们之前也介绍过,当我们执行pull的时候,其实是执行了git fetch和git merge两个步骤。所以相当于我们把master分支的改动又merge了一次,我们本地依赖了rebase之前的改动,这样一merge自然就把两个版本的改动merge在一起了。
要解决这个问题,我们就不能在C8节点的时候进行pull操作,因为pull操作包含merge,merge会导致错误。要解决这个问题其实也不难,我们可以rebase到master上。当我们执行rebase的时候,git会找出我们当前分支独有而master分支上没有的改动,将这些改动提取出来应用在master上得到一个新的结果。

这样我们的记录当中就不会把C2和C5带进来了。
发散思考
我们贯通思考一下上面的过程,会得到一个什么结论?
其实结论很简单,就是rebase虽然很好用也很方便,但是它也有适用的条件,其中最大的条件就是如果还有其他分支依赖了当前分支,我们这时候不可以使用rebase,否则一定会引起错乱。
那引起错乱的原因又是什么呢?本质上是我们rebase的时候修改了commit的记录,关于这一点不同的人有不同的观点。有一派人认为git的提交记录是不可以篡改的,它存在的意义就是记录repo当中所有发生过的改动。如果使用rebase等操作进行了篡改,那么我们就不能很好地追溯之前的改动和版本了。还有一派人不这么看,他们觉得如果记录的改动非常混乱非常不方便使用者阅读,这时候使用一些方法对它进行修整就是非常有必要的事情。工具发明出来就是为了使用的。
这两派争论不休,不同的人有不同的看法,可以说是一个价值观问题也不为过。在这个问题上我个人更加偏向后者, 既然有这么好用的工具,自然应该使用的。使用不是滥用,我们需要遵守一定的规范,这样才能保证不会捅出篓子来。比如一定不可以在下游还有其他依赖的情况下使用rebase,否则几乎可以肯定是一定会捅娄子的。
今天的文章就到这里,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发)
本文使用 mdnice 排版

git rebase的时候捅娄子了,怎么办?在线等……的更多相关文章
- git rebase VS git merge? 更优雅的 git 合并方式值得拥有
写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online ,你可以更直观的看到你所使用的命令会产生什么效果 另外,你在使用 Git 合并分支时只 ...
- git rebase VS git merge
git rebase VS git merge 写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online(回复公众号「工具」,获取更多内容) , ...
- git rebase
git rebase -i HEAD~[number_of_commits] git rebase -i HEAD~2
- git rebase与 git合并(error: failed to push some refs to)解决方法
1.遇到的问题 本地有一个git仓库,在github上新建了一个空的仓库,但是更新了REWADME.md的信息,即在github上多了一个提交. 关联远程仓库,操作顺序如下: git remote a ...
- 聊下 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 rebase -i
使用rebase -i会在终端出现一个交互页面. 在这个交互页面中我们可以对要rebase的commit做一定的修改. 用法 git rebase -i <master> 把当前的分支的c ...
- [译]git rebase
rebase就是重新定义你分支的起点, 分支上的commit将生成对应的新的commit并放在你指定的新的起点commit后, 分支上的老commit将被删除. rebase就是将你的分支从一个com ...
随机推荐
- 03 以Hello World为例,分析C语言的最小的程序结构
C程序主要包含的部分 预处理器指令 函数 变量 语句 & 表达式 注释 C Hello World 实例 如下程序,可以在屏幕输出短句"Hello World" #incl ...
- Golang搭建接口测试框架
测试报告 使用goconvey作为测试报告,使用方法: 安装 $ go get github.com/smartystreets/goconvey $ $GOPATH/bin/goconvey 导入包 ...
- Android作业10/07
1.多个Activity界面实现数据的传递 <?xml version="1.0" encoding="utf-8"?> <androidx. ...
- JVM 第三篇:Java 类加载机制
本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 什么是类的加载? 类的加载指的是将类的 .class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 ...
- RHSA-2018:0395-重要: 内核 安全和BUG修复更新(需要重启、本地提权、代码执行)
[root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...
- TTL电平,CMOS电平,232/485电平,OC门,OD门基础知识
1.RS232电平 或者说串口电平,有的甚至说计算机电平,所有的这些说法,指得都是计算机9针串口 (RS232)的电平,采用负逻辑, -15v ~ -3v 代表1 +3v ~ +15v 代表0 2. ...
- 福州11911.562(薇)xiaojie:福州哪里有xiaomei
福州哪里有小姐服务大保健[微信:11911.562倩儿小妹[福州叫小姐服务√o服务微信:11911.562倩儿小妹[福州叫小姐服务][十微信:11911.562倩儿小妹][福州叫小姐包夜服务][十微信 ...
- 晋城6397.7539(薇)xiaojie:晋城哪里有xiaomei
晋城哪里有小姐服务大保健[微信:6397.7539倩儿小妹[晋城叫小姐服务√o服务微信:6397.7539倩儿小妹[晋城叫小姐服务][十微信:6397.7539倩儿小妹][晋城叫小姐包夜服务][十微信 ...
- Mysql架构与内部模块-第一章
Mysql作为大多数中小型企业的首选数据库,也可能是众多同僚接触的第一个数据库,其热门程度不言而喻,一些相对基础的知识本系列不做赘述,主要简述Mysql相关的进阶知识. 本章将由浅入深的讲解从连接My ...
- PJzhang:Firefox渗透测试插件HackTools样例
猫宁~~~ firefox插件hacktools地址: https://addons.mozilla.org/zh-CN/firefox/addon/hacktools/ HackTools由Ludo ...