Git 之 revert

剪秋罗迭代
• 阅读 31517

revert 可以取消指定的提交内容。

当讨论 revert 时,需要分两种情况,因为 commit 分为两种:一种是常规的 commit,也就是使用 git commit 提交的 commit;另一种是 merge commit,在使用 git merge 合并两个分支之后,你将会得到一个新的 merge commit

merge commit 和普通 commit 的不同之处在于 merge commit 包含两个 parent commit,代表该 merge commit 是从哪两个 commit 合并过来的。

Git 之 revert

在上图所示的红框中有一个 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

revert 常规 commit

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

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

revert 之后重新上线

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

a -> b -> c -> f -- g -> h (master)
           \      /
            d -> e   (goudan/a-cool-feature)

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

a -> b -> c -> f -- g -> h -> G (master)
           \      /
            d -> e   (goudan/a-cool-feature)

然后狗蛋回到自己的分支进行 bugfix,修好之后想重新合并到 master,直觉上只需要再 merge 到 master 即可(或者使用 cherry-pick),像这样:

a -> b -> c -> f -- g -> h -> G -> i (master)
           \      /               /
            d -> e -> j -> k ----    (goudan/a-cool-feature)

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

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

a -> b -> c -> f -- g -> h -> G -> G' -> i (master)
           \      /                     /
            d -> e -> j -> k ----------    (goudan/a-cool-feature)

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

参考

http://blog.psjay.com/posts/git-revert-merge-commit/

https://stackoverflow.com/questions/9059335/get-parents-of-a-merge-commit-in-git

点赞
收藏
评论区
推荐文章
Stella981 Stella981
3年前
Git撤销已经推送(push)至远端仓库的提交(commit)信息
有时,在gitpush之后,才发现还有一些代码需要进行很小的改动,这些改动在原则上不应该作为一次新的提交。这时,我们需要撤销这次推送(gitpush)与提交(gitcommit),然后进行代码修改,再重新进行提交和推送。为了实现这个目的,需要进行三步操作。1.撤销提交信息首先,通过gitlog查看提交信息,以便获取需要回退至的版
Stella981 Stella981
3年前
Apache Hudi Rollback实现分析
1\.介绍在发现有些commit出错时,可使用Hudi提供的rollback回滚至指定的commit,这样可防止出现错误的结果,并且当一次commit失败时,也会进行rollback操作,保证一次commit的原子性。2\.分析rollback(回滚)的入口在HoodieWriteClientrollback,其
Stella981 Stella981
3年前
Git 对象存储结构分析
1\.前言git对象有四种:blob(数据块),tree(目录树),commit(提交),tag(标签)。本文通过一个示例,以blob为例来讨论对象的存储结构。示例采用的git版本为2.17。2\.实践讨论2.1.生成Blob对象文件首先创建一
Wesley13 Wesley13
3年前
mysql innodb和myisam比较
1.MySQL默认采用的是MyISAM。2.MyISAM不支持事务,而InnoDB支持。InnoDB的AUTOCOMMIT默认是打开的,即每条SQL语句会默认被封装成一个事务,自动提交,这样会影响速度,所以最好是把多条SQL语句显示放在begin和commit之间,组成一个事务去提交。3.InnoDB支持数据行锁定,MyISAM不支持行锁定,
Stella981 Stella981
3年前
Git 实战教程
1.Git配置使用Git的第一件事就是设置你的名字和email,这些就是你在提交commit时的签名,每次提交记录里都会包含这些信息。使用gitconfig命令进行配置:​$gitconfigglobaluser.name"ilimhumar"$gitconfigglobal
Stella981 Stella981
3年前
Spring Kafka中关于Kafka的配置参数
consumer的配置参数(开始)如果'enable.auto.commit'为true,则消费者偏移自动提交给Kafka的频率(以毫秒为单位),默认值为5000。spring.kafka.consumer.autocommitinterval;当Kafka中
Wesley13 Wesley13
3年前
Git中代码冲突的解决方式
使用Git管理代码,在进行代码提交的时候,如果出现了冲突该怎么办呢,下面就两种常见的冲突给出了解决方法,希望对大家有所帮助。冲突1:当你commit以后,在执行gitpullrebase的时候出现冲突,请按如下步骤解决:1 找到冲突文件,解决冲突2 执行gitaddxxx(xxx为冲突文件全路径)3 执行git
Wesley13 Wesley13
3年前
MySQL二进制日志系列
MySQL二进制日志系列总结1、binarylog记录的是 已经提交commit的各种DML和DDL语句,类似oracle的redolog(包含onlineredolog和archiveredolog)中已经commit提交的数据statement格式的binlog,最后会有COMMIT; 
Wesley13 Wesley13
3年前
Mysql技术总结总结
一:mysql数据库引擎MyISAM和InnoDB的区别:1、MyISAM具有检查和修复表格的大多数工具。表格可以被压缩,而且支持全文收索。不支持事物,而且不支持外键。2、innodb这种表是事务安全的。提供了commit(提交)rollback(实务回滚)支持外键,
Stella981 Stella981
3年前
Git commit message和工作流规范
作者:程柳锋目的统一团队Gitcommit日志标准,便于后续代码review,版本发布以及日志自动化生成等等。统一团队的Git工作流,包括分支使用、tag规范、issue等Gitcommit日志参考案例angular(https://www.oschina.net/action/GoToL
Stella981 Stella981
3年前
MariaDB系统参数binlog_commit_wait_count引起的单线程单表插入性能低下问题
binlog\_commit\_wait\_count和binlog\_commit\_wait\_usec两个参数是MariaDB10.0开始引入的新参数,根据官方文档介绍:binlog\_commit\_wait\_countDescription:Foruseinparallelreplication(