1. git revert 作用

  revert 用来取消置顶的提交的内容

2. 前提说明

  当讨论 revert 时,需要分两种情况,因为 commit 分为两种:

  • 一种是常规的 commit,也就是使用 git commit 提交的 commit;
  • 另一种是 merge commit

  需要明确:在使用 git merge 合并两个分支之后,你将会得到一个新的 merge commit。merge commit 和普通 commit 的不同之处在于 merge commit 包含两个 parent commit,代表该 merge commit 是从哪两个 commit 合并过来的。

  

  在上图所示的红框中有一个 merge commit,使用 git show 命令可以查看 commit 的详细信息

  ➜  git show bd86846
  commit bd868465569400a6b9408050643e5949e8f2b8f5
  Merge: ba25a9d 1c7036f

  这代表该 merge commit 是从 ba25a9d 和 1c7036f 两个 commit 合并过来的。

  而常规的 commit 则没有 Merge 行

  ➜  git show 3e853bd
  commit 3e853bdcb2d8ce45be87d4f902c0ff6ad00f240a

3. revert 常规 commit

  使用 git revert <commit id> 即可,git 会生成一个新的 commit,将指定的 commit 内容从当前分支上撤除。

4. revert merge commit

  revert merge commit 有一些不同,这时需要添加 -m 选项以代表这次 revert 的是一个 merge commit

  但如果直接使用 git revert <commit id>,git 也不知道到底要撤除哪一条分支上的内容,这时需要指定一个 parent number 标识出"主线",主线的内容将会保留,而另一条分支的内容将被 revert。

  如上面的例子中,从 git show 命令的结果中可以看到,merge commit 的 parent 分别为 ba25a9d 和 1c7036f,其中 ba25a9d 代表 master 分支(从图中可以看出),1c7036f 代表 will-be-revert 分支。需要注意的是 -m 选项接收的参数是一个数字,数字取值为 1 和 2,也就是 Merge 行里面列出来的第一个还是第二个。

  我们要 revert will-be-revert 分支上的内容,即 保留主分支,应该设置主分支为主线,操作如下:

  ➜ git revert -m 1 bd86846

5. revert 之后重新上线

  假设你自己分支 goudan/a-cool-feature 上开发了一个功能,并合并到了 master 上,之后 master 上又提交了一个修改 h,这时提交历史如下:

  

  突然,大家发现你的分支存在严重的 bug,需要 revert 掉,于是大家把 g 这个 merge commit revert 掉了,记为 G,如下:

  

  然后你回到自己的分支进行 bug_fix,修好之后想重新合并到 master,直觉上只需要再 merge 到 master 即可

  

  i 是新的 merge commit。但需要注意的是,这 不能 得到我们期望的结果。因为 d 和 e 两个提交曾经被丢弃过,如此合并到 master 的代码,并不会重新包含 d 和 e 两个提交的内容,相当于只有 goudan/a-cool-feature 上的新 commit 被合并了进来,而 goudan/a-cool-feature 分支之前的内容,依然是被 revert 掉了。

  所以,如果想恢复整个 goudan/a-cool-feature 所做的修改,应该先把 G revert 掉:

  

  其中 G' 是对 G 的 revert 操作生成的 commit,把之前撤销合并时丢弃的代码恢复了回来,然后再 merge 狗蛋的分支,把解决 bug 写的新代码合并到 master 分支。

  可以通俗的来理解:相对你自己 G 是通过别人来远程操作的 revert 操作,相对于别人来说此时的 master 分支已经不存在 d 和 e 两个提交的内容,而你自己本地分支上并没有进行 revert 操作,相对于其他人来说你本地认为 master 分支还保存有 d 和 e 提交的内容,如果直接合并的话会报错,故需要你自己在本地直接 revert 操作,将 g 点联系释放掉,和线上原始 master 分支保持干净完整的链路,这样就可以正常的 merge commit 了。

6. revert 和 reset 区别

  1. git revert 是用一次新的 commit 来回滚之前的 commit,git reset 是直接删除指定的 commit。
  2. 在回滚这一操作上看,效果差不多。但是在日后继续 merge 以前的老版本时有区别。因为 git
    revert 是用一次逆向的 commit “中和” 之前的提交,因此日后合并老的 branch 时,导致这部分改变不会再次出现,但是 git
    reset 是直接把某些 commit 在某个 branch 上删除,因而和老的 branch 再次 merge 时,这些被回滚的commit应该还会被引入。
  3. git reset 是把 HEAD 向后移动了一下,而 git revert 是HEAD继续前进,只是新的 commit 的内容和要 revert 的内容正好相反,能够抵消要被 revert 的内容。

git 线上回滚问题纪要的更多相关文章

  1. git代码回滚:Reset、Checkout、Revert的选择

    代码回滚:Reset.Checkout.Revert的选择 Zhongyi Tong edited this page on Dec 8, 2015 · 5 revisions Pages 19 Ho ...

  2. Git如何回滚代码?

    摘要: 多年以后,你面对一个需要回滚的Git仓库,准会想起这篇博客. 某一天,用户跟我反馈,他不能分配任务了.我去看了一下Fundebug捕获的报错信息: 可知,出错原因是前端发送的请求参数有问题.这 ...

  3. git代码回滚的两种选择

    回滚到指定commit,且保持该commit之前和之后的提交记录 使用git revert命令. git revert HEAD // 回滚到前一次 commit git revert HEAD^ / ...

  4. git如何回滚当前修改的内容?

    git如何回滚当前修改的内容? 1.打开git gui,在工具栏上点击 commit ,选择 Revert Changes,  这里可以回滚单个文件: 2.一键回滚所有修改: 打开git gui,在工 ...

  5. Git撤销&回滚操作

    https://blog.csdn.net/ligang2585116/article/details/71094887 开发过程中,你肯定会遇到这样的场景: 场景一: 糟了,我刚把不想要的代码,co ...

  6. Git撤销&回滚操作(git reset 和 get revert)

    转自:https://blog.csdn.net/asoar/article/details/84111841 git的工作流 工作区:即自己当前分支所修改的代码,git add xx 之前的!不包括 ...

  7. git版本号回滚

    先说今天遇到的问题,看到一个config.php的配置文件一直在改动的状态下,可是和远程的config.php是不一致的,我不须要提交它,可是看它在 modified的状态下,非常不爽.想删除它.gi ...

  8. git 版本回滚

    1.克隆代码到本地 git clone http://qtools@dev.qtoolsbaby.cn:81/gitlab/qtools/jenkins_ceshi.git 2.git log 查看所 ...

  9. 6.Git代码回滚

    1.代码修改并提交 我们已经成功地添加并提交了一个helloWorld.txt文件,现在,是时候继续工作了. 于是,我们继续修改helloWorld.txt文件,改成如下内容: $ vi helloW ...

随机推荐

  1. 《Linux内核设计与实现》第五章学习笔记

    <Linux内核设计与实现>第五章学习笔记 姓名:王玮怡  学号:20135116 一.与内核通信     在Linux中,系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核 ...

  2. 个人实验 github地址:https://github.com/quchengyu/cher

    一.实践目的 1.掌握类的定义,对象的创建. 2.掌握实现封装.继承.多态的方法,掌握各种修饰符的使用. 3.掌握将对象数组作为方法的参数和返回值. 4.掌握抽象类与接口的概念及实现,理解动态绑定机制 ...

  3. C++高质量编程笔记

    /* * 函数介绍: * 输入参数: * 输出参数: * 返回值 : */ void Function(float x, float y, float z) { - } if (-) { - whil ...

  4. logstash 解析日志文件

    input { file { path => "/usr/local/test/log.log" } } filter { grok { match => { &quo ...

  5. Java提高篇(1)封装

    三大特性之---封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能 ...

  6. Sprint 冲刺第三阶段第3-5天 数据库代码

    数据库代码: package com.example.brdemo; import android.app.Activity; import android.content.Intent; impor ...

  7. 我的software

    每个学计算机软件的同学都有可能经历以下的情况: 1.  哎,我家电脑开不了机了,来帮帮忙 2.  我耳机坏了,你给修修吧 3.  你能换手机屏不 4.  过来看下,我的Word打不开了 等等等等 这些 ...

  8. [BUAA_SE_2017]案例分析-Week3

    Week3 案例分析 一.调研评测 案例: 神策数据的数据概览功能 Demo: 电商类产品Demo 评价: d) 好,不错 个人评价:神策数据电商类产品Demo的数据概览功能是相当不错的.首先点击进入 ...

  9. PAT 1032 挖掘机技术哪家强

    https://pintia.cn/problem-sets/994805260223102976/problems/994805289432236032 为了用事实说明挖掘机技术到底哪家强,PAT组 ...

  10. 搭建Spark所遇过的坑

    一.经验 1.Spark Streaming包含三种计算模式:nonstate .stateful .window 2.kafka可通过配置文件使用自带的zookeeper集群 3.Spark一切操作 ...