大家在使用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 排版

![](https://img2020.cnblogs.com/blog/1906483/202011/1906483-20201106162335841-274694996.png)

git rebase的时候捅娄子了,怎么办?在线等……的更多相关文章

  1. git rebase VS git merge? 更优雅的 git 合并方式值得拥有

    写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online ,你可以更直观的看到你所使用的命令会产生什么效果 另外,你在使用 Git 合并分支时只 ...

  2. git rebase VS git merge

    git rebase VS git merge 写在前面 如果你不能很好的应用 Git,那么这里为你提供一个非常棒的 Git 在线练习工具 Git Online(回复公众号「工具」,获取更多内容) , ...

  3. git rebase

    git rebase -i HEAD~[number_of_commits] git rebase -i HEAD~2

  4. git rebase与 git合并(error: failed to push some refs to)解决方法

    1.遇到的问题 本地有一个git仓库,在github上新建了一个空的仓库,但是更新了REWADME.md的信息,即在github上多了一个提交. 关联远程仓库,操作顺序如下: git remote a ...

  5. 聊下 git rebase -i

    在使用git作为源代码管理工具的时候,开发的时经常会面临一个常见的问题,多个commit 需要合并为一个完整的commit提交. 在一个基本的迭代周期里,你会有很多次commit,有跟配置文件相关的, ...

  6. [git]rebase和merge

    转自:http://blog.csdn.net/wh_19910525/article/details/7554489 Git merge是用来合并两个分支的. git merge b # 将b分支合 ...

  7. git merge 和 git rebase 小结

    Git merge是用来合并两个分支的. git merge b # 将b分支合并到当前分支 同样 git rebase b,也是把 b分支合并到当前分支 ---------------------- ...

  8. [译]git rebase -i

    使用rebase -i会在终端出现一个交互页面. 在这个交互页面中我们可以对要rebase的commit做一定的修改. 用法 git rebase -i <master> 把当前的分支的c ...

  9. [译]git rebase

    rebase就是重新定义你分支的起点, 分支上的commit将生成对应的新的commit并放在你指定的新的起点commit后, 分支上的老commit将被删除. rebase就是将你的分支从一个com ...

随机推荐

  1. 03 以Hello World为例,分析C语言的最小的程序结构

    C程序主要包含的部分 预处理器指令 函数 变量 语句 & 表达式 注释 C Hello World 实例 如下程序,可以在屏幕输出短句"Hello World" #incl ...

  2. Golang搭建接口测试框架

    测试报告 使用goconvey作为测试报告,使用方法: 安装 $ go get github.com/smartystreets/goconvey $ $GOPATH/bin/goconvey 导入包 ...

  3. Android作业10/07

    1.多个Activity界面实现数据的传递 <?xml version="1.0" encoding="utf-8"?> <androidx. ...

  4. JVM 第三篇:Java 类加载机制

    本文内容过于硬核,建议有 Java 相关经验人士阅读. 1. 什么是类的加载? 类的加载指的是将类的 .class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 ...

  5. RHSA-2018:0395-重要: 内核 安全和BUG修复更新(需要重启、本地提权、代码执行)

    [root@localhost ~]# cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 修复命令: 使用root账号登陆She ...

  6. TTL电平,CMOS电平,232/485电平,OC门,OD门基础知识

     1.RS232电平 或者说串口电平,有的甚至说计算机电平,所有的这些说法,指得都是计算机9针串口 (RS232)的电平,采用负逻辑, -15v ~ -3v 代表1 +3v ~ +15v 代表0 2. ...

  7. 福州11911.562(薇)xiaojie:福州哪里有xiaomei

    福州哪里有小姐服务大保健[微信:11911.562倩儿小妹[福州叫小姐服务√o服务微信:11911.562倩儿小妹[福州叫小姐服务][十微信:11911.562倩儿小妹][福州叫小姐包夜服务][十微信 ...

  8. 晋城6397.7539(薇)xiaojie:晋城哪里有xiaomei

    晋城哪里有小姐服务大保健[微信:6397.7539倩儿小妹[晋城叫小姐服务√o服务微信:6397.7539倩儿小妹[晋城叫小姐服务][十微信:6397.7539倩儿小妹][晋城叫小姐包夜服务][十微信 ...

  9. Mysql架构与内部模块-第一章

    Mysql作为大多数中小型企业的首选数据库,也可能是众多同僚接触的第一个数据库,其热门程度不言而喻,一些相对基础的知识本系列不做赘述,主要简述Mysql相关的进阶知识. 本章将由浅入深的讲解从连接My ...

  10. PJzhang:Firefox渗透测试插件HackTools样例

    猫宁~~~ firefox插件hacktools地址: https://addons.mozilla.org/zh-CN/firefox/addon/hacktools/ HackTools由Ludo ...