git 线上回滚问题纪要
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 区别
- git revert 是用一次新的 commit 来回滚之前的 commit,git reset 是直接删除指定的 commit。
- 在回滚这一操作上看,效果差不多。但是在日后继续 merge 以前的老版本时有区别。因为 git
revert 是用一次逆向的 commit “中和” 之前的提交,因此日后合并老的 branch 时,导致这部分改变不会再次出现,但是 git
reset 是直接把某些 commit 在某个 branch 上删除,因而和老的 branch 再次 merge 时,这些被回滚的commit应该还会被引入。 - git reset 是把 HEAD 向后移动了一下,而 git revert 是HEAD继续前进,只是新的 commit 的内容和要 revert 的内容正好相反,能够抵消要被 revert 的内容。
git 线上回滚问题纪要的更多相关文章
- git代码回滚:Reset、Checkout、Revert的选择
代码回滚:Reset.Checkout.Revert的选择 Zhongyi Tong edited this page on Dec 8, 2015 · 5 revisions Pages 19 Ho ...
- Git如何回滚代码?
摘要: 多年以后,你面对一个需要回滚的Git仓库,准会想起这篇博客. 某一天,用户跟我反馈,他不能分配任务了.我去看了一下Fundebug捕获的报错信息: 可知,出错原因是前端发送的请求参数有问题.这 ...
- git代码回滚的两种选择
回滚到指定commit,且保持该commit之前和之后的提交记录 使用git revert命令. git revert HEAD // 回滚到前一次 commit git revert HEAD^ / ...
- git如何回滚当前修改的内容?
git如何回滚当前修改的内容? 1.打开git gui,在工具栏上点击 commit ,选择 Revert Changes, 这里可以回滚单个文件: 2.一键回滚所有修改: 打开git gui,在工 ...
- Git撤销&回滚操作
https://blog.csdn.net/ligang2585116/article/details/71094887 开发过程中,你肯定会遇到这样的场景: 场景一: 糟了,我刚把不想要的代码,co ...
- Git撤销&回滚操作(git reset 和 get revert)
转自:https://blog.csdn.net/asoar/article/details/84111841 git的工作流 工作区:即自己当前分支所修改的代码,git add xx 之前的!不包括 ...
- git版本号回滚
先说今天遇到的问题,看到一个config.php的配置文件一直在改动的状态下,可是和远程的config.php是不一致的,我不须要提交它,可是看它在 modified的状态下,非常不爽.想删除它.gi ...
- git 版本回滚
1.克隆代码到本地 git clone http://qtools@dev.qtoolsbaby.cn:81/gitlab/qtools/jenkins_ceshi.git 2.git log 查看所 ...
- 6.Git代码回滚
1.代码修改并提交 我们已经成功地添加并提交了一个helloWorld.txt文件,现在,是时候继续工作了. 于是,我们继续修改helloWorld.txt文件,改成如下内容: $ vi helloW ...
随机推荐
- 《Linux内核设计与实现》第五章学习笔记
<Linux内核设计与实现>第五章学习笔记 姓名:王玮怡 学号:20135116 一.与内核通信 在Linux中,系统调用是用户空间访问内核的唯一手段:除异常和陷入外,它们是内核 ...
- 个人实验 github地址:https://github.com/quchengyu/cher
一.实践目的 1.掌握类的定义,对象的创建. 2.掌握实现封装.继承.多态的方法,掌握各种修饰符的使用. 3.掌握将对象数组作为方法的参数和返回值. 4.掌握抽象类与接口的概念及实现,理解动态绑定机制 ...
- C++高质量编程笔记
/* * 函数介绍: * 输入参数: * 输出参数: * 返回值 : */ void Function(float x, float y, float z) { - } if (-) { - whil ...
- logstash 解析日志文件
input { file { path => "/usr/local/test/log.log" } } filter { grok { match => { &quo ...
- Java提高篇(1)封装
三大特性之---封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能 ...
- Sprint 冲刺第三阶段第3-5天 数据库代码
数据库代码: package com.example.brdemo; import android.app.Activity; import android.content.Intent; impor ...
- 我的software
每个学计算机软件的同学都有可能经历以下的情况: 1. 哎,我家电脑开不了机了,来帮帮忙 2. 我耳机坏了,你给修修吧 3. 你能换手机屏不 4. 过来看下,我的Word打不开了 等等等等 这些 ...
- [BUAA_SE_2017]案例分析-Week3
Week3 案例分析 一.调研评测 案例: 神策数据的数据概览功能 Demo: 电商类产品Demo 评价: d) 好,不错 个人评价:神策数据电商类产品Demo的数据概览功能是相当不错的.首先点击进入 ...
- PAT 1032 挖掘机技术哪家强
https://pintia.cn/problem-sets/994805260223102976/problems/994805289432236032 为了用事实说明挖掘机技术到底哪家强,PAT组 ...
- 搭建Spark所遇过的坑
一.经验 1.Spark Streaming包含三种计算模式:nonstate .stateful .window 2.kafka可通过配置文件使用自带的zookeeper集群 3.Spark一切操作 ...