Git 实用操作 | 撤销 Commit 提交

有的时候,改完代码提交 commit 后发现写得实在太烂了,连自己的都看不下去,与其修改它还不如丢弃重写。怎么操作呢?

使用 reset 撤销

如果是最近提交的 commit 要丢弃重写可以用 reset 来操作。比如你刚写了一个 commit:

写完回头看了看,你觉得不行这得重新写。那么你可以用 reset --hard 来撤销这条 commit。

git reset --hard HEAD^

HEAD^ 表示往回数一个位置的 commit`,上篇刚说过。

因为你要撤销最新的一个 commit,所以你需要恢复到它的父 commit ,也就是 HEAD^。那么在这行之后,你要丢弃的最新一条就被撤销了:

不过,就像图上显示的,你被撤销的那条提交并没有消失,只是你不再用到它了。如果你在撤销它之前记下了它的 SHA-1 码,那么你还可以通过 SHA-1 来找到他它。

使用 rebase -i 撤销

假如有一个 commit,你在刚把它写完的时候并没有觉得它不好,可是在之后又写了几个提交以后,你突然灵光一现:哎呀,那个 commit 不该写,我要撤销!

不是最新的提交,就不能用 reset --hard 来撤销了。这种情况的撤销,就要用之前介绍过的一个指令交互式变基:rebase -i

之前介绍过,交互式变基可以用来修改某些旧的 commit。其实除了修改提交,它还可以用于撤销提交。比如下面这种情况:

你想撤销倒数第二条 commit,那么可以使用 rebase -i

git rebase -i HEAD^^

Git 引导到选择要操作的 commit 页面:

pick 310154e 第 N-2 次提交
pick a5f4a0d 第 N-1 次提交# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
...

在上篇中,讲到要修改哪个 commit 就把哪个 commit 前面的 pick 改成 edit。而如果你要撤销某个 commit ,做法就更加简单粗暴一点:直接删掉这一行就好(使用 d 命令)。

pick a5f4a0d 第 N-1 次提交# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
...

把这一行删掉就相当于在 rebase 的过程中跳过了这个 commit,从而也就把这个 commit 丢弃了。

如果你通过 git log 查看,就会发现之前的倒数第二条 commit 已经不在了。

使用用 rebase --onto 撤销

除了用交互式 rebase,你还可以用 rebase --onto 来更简便地撤销提交。

rebase 加上 --onto 选项之后,可以指定 rebase 的「起点」。一般的 rebase, 的「起点」是自动选取的,选取的是当前 commit 和目标 commit 在历史上的交叉点。

例如下面这种情况:

如果在这里执行:

git rebase 第3个commit

那么 Git 会自动选取 35 的历史交叉点 2 作为 rebase 的起点,依次将 45 重新提交到 3 的路径上去。

--onto 参数,就可以额外给 rebase 指定它的起点。例如同样以上图为例,如果我只想把 5 提交到 3 上,不想附带上 4,那么我可以执行:

git rebase --onto 第3个commit 第4个commit branch1

选项 --onto 参数后面有三个附加参数:目标 commit、起点 commit(注意:rebase 的时候会把起点排除在外)、终点 commit。所以上面这行指令就会从 4 往下数,拿到 branch1 所指向的 5,然后把 5 重新提交到 3 上去。

同样的,你也可以用 rebase --onto 来撤销提交:

git rebase --onto HEAD^^ HEAD^ branch1

上面这行代码的意思是:以倒数第二个 commit 为起点(起点不包含在 rebase 序列里),branch1 为终点,rebase 到倒数第三个 commit 上。

也就是这样:

总结

撤销最近一次的 commit 直接使用 reset --hard,撤销过往历史提交。方法有两种:

  1. git rebase -i 在编辑界面中删除想撤销的 commit

  2. git rebase --onto 在 rebase 命令中直接剔除想撤销的 commit

这有两种理念是一样的,即在 rebase 的过程中去掉想撤销的 commit,让它消失在历史中。

-

精致码农

带你洞悉编程与架构

↑长按图片识别二维码关注,不要错过网海相遇的缘分

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

react只停留在表层?五大知识点带你梳理进阶知识

五大知识点带你梳理react进阶知识✉️前言&#x1f4e7;一、props1、PropTypes与DefaultProps应用&#xff08;1&#xff09;PropTypes&#xff08;2&#xff09;defaultProps2、props&#xff0c;state与render函数&#x1f4e8;二、React中的虚拟DOM1、什么是虚拟DOM&#xf…

解决 WPF 绑定集合后数据变动界面却不更新的问题

解决 WPF 绑定集合后数据变动界面却不更新的问题独立观察员 2020 年 9 月 9 日在 .NET Core 3.1 的 WPF 程序中打算用 ListBox 绑定显示一个集合&#xff08;满足需求即可&#xff0c;无所谓什么类型的集合&#xff09;&#xff0c;以下是 Xaml 代码&#xff08;瞟一眼就行&…

「offer来了」面试中必考的15个html知识点

「面试专栏」前端面试之html篇⚡序言⭐一、题集内容抢先看&#x1f320;二、规范相关1、你如何理解HTML结构的语义化2、浏览器是怎么对 Html5 的离线储存资源进行管理和加载的呢3、HTML W3C的标准4、Doctype作用? 严格模式与混杂模式如何区分&#xff1f;它们有何意义?5、vie…

leetcode700. 二叉搜索树中的搜索

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}*…

「offer来了」1张思维导图,6大知识板块,带你梳理面试中CSS的知识点!

「面试专栏」前端面试之css篇⌛序言✏️一、CSS框架先梳理&#x1f58c;️二、基础样式问题1、请你讲一讲css的权重和优先级&#xff08;1&#xff09;权重&#xff08;2&#xff09;优先级2、说一下CSS的position属性3、span 标签是否可以设置宽高&#xff0c; margin 和 padd…

动态代理的理解

一:动态代理和静态代理的区别 静态代理&#xff1a;了解设计模式中的代理模式的童鞋应该都知道&#xff0c;如果想要生成代理类&#xff0c;需要让代理类和被代理类实现同一个接口&#xff0c;并且在代理类中添加被代理类的引用&#xff0c;代理类方法实现中添加代理逻辑&…

.NET Core 下的爬虫利器

爬虫大家或多或少的都应该接触过的&#xff0c;爬虫有风险&#xff0c;抓数需谨慎。本着研究学习的目的&#xff0c;记录一下在 .NET Core 下抓取数据的实际案例。爬虫代码一般具有时效性&#xff0c;当我们的目标发生改版升级&#xff0c;规则转换后我们写的爬虫代码就会失效&…

Redux从入门到进阶,看这一篇就够了!

Redux&#xff0c;带你从入门到进阶&#x1f302;序言☂️一、基础知识1、Redux概念简述2、Redux的工作流程&#x1f383;二、使用Antd实现TodoList页面布局1、在项目中使用Antd2、使用Antd实现TodoList的基本布局3、创建redux中的store&#xff08;1&#xff09;创建store&…

ASP.NET Core 3.x控制IHostedService启动顺序浅探

想写好中间件&#xff0c;这是基础。一、前言今天这个内容&#xff0c;基于于ASP.NET Core 3.x。从3.x开始&#xff0c;ASP.NET Core使用了通用主机模式。它将WebHostBuilder放到了通用的IHost之上&#xff0c;这样可以确保Kestrel可以运行在IHostedService中。我们今天就来研究…

com.mysql.cj.exceptions.InvalidConnectionAttributeException

一:java连接数据库报错 com.mysql.cj.exceptions.InvalidConnectionAttributeException 二:报错原因 MySQL jdbc 6.0 版本以上必须配置“serverTimezone”参数 UTC代表的是全球标准时间 若我们使用的时间是北京时区也就是东八区&#xff0c;领先UTC八个小时。url的时区使用…

Istio Pilot 源码分析(一)

张海东&#xff0c; ‍多点生活&#xff08;成都&#xff09;云原生开发工程师。Istio 作为目前 Servic Mesh 方案中的翘楚&#xff0c;吸引着越来越多的企业及开发者。越来越多的团队想将其应用于微服务的治理&#xff0c;但在实际落地时却因为不了解 Istio 黑盒中的运行机制而…

结营啦!有缘相聚于青训,未来高处见呀~~

&#x1f4f8;叮&#xff01; 记 字节跳动第一届青训营顺利结营啦&#xff01; 从8月份的青训营&#xff0c;到9月份的实训营&#xff0c;搁置了许久的结营心得终于拾起来辽&#xff01; &#x1f3ac;开营进行时 从答疑会开始&#xff0c;负责人仔细的阐述了本次训练营的…

MVC三层架构(详解)

1:初始MVC (1):三层架构 三层架构是指&#xff1a;视图层 View、服务层 Service&#xff0c;与持久层 Dao。它们分别完成不同的功能。 View 层&#xff1a;用于接收用户提交请求的代码在这里编写。 Service 层&#xff1a;系统的业务逻辑主要在这里完成。 Dao 层&#xff1a;…

「offer来了」保姆级巩固你的js知识体系(4.0w字)

「面试专栏」前端面试之JavaScript篇&#x1f9d0;序言&#x1f973;思维导图环节&#x1f60f;一、JS规范1、说几条JavaScript的基本规范。2、对原生JavaScript的了解。3、说下对JS的了解吧。4、JS原生拖拽节点5、谈谈你对ES6的理解6、知道ES6的class嘛&#xff1f;7、说说你对…

写作是人生最大的杠杆

职场&认知洞察 丨 作者 / 易洋 这是findyi公众号的第71篇原创文章不知不觉&#xff0c;公众号写作已经持续了9个月了。去年11月底&#xff0c;心血来潮写了第一篇文章&#xff0c;更多是为了复盘过去的一些工作经历。在前几天&#xff0c;读者数突破了3万&#xff0c;虽然…

拥塞控制(详解)

一&#xff1a;TCP的拥塞控制 1:是什么 (1):是什么(拥塞现象) 网络的 吞吐量 与 通信子网 负荷(即通信子网中正在传输的分组数)有着密切的关系。当 通信子网 负荷比较小时,网络的 吞吐量 (分组数/秒)随网络负荷(每个 节点 中分组的平均数)的增加而线性增加。当网络负荷增加到…

解决 WPF 绑定集合后数据变动界面却不更新的问题(使用 ObservableCollection)

解决 WPF 绑定集合后数据变动界面却不更新的问题独立观察员 2020 年 9 月 9 日在 .NET Core 3.1 的 WPF 程序中打算用 ListBox 绑定显示一个集合&#xff08;满足需求即可&#xff0c;无所谓什么类型的集合&#xff09;&#xff0c;以下是 Xaml 代码&#xff08;瞟一眼就行&…

Kubernetes Liveness and Readiness Probes

在设计关键任务、高可用应用程序时&#xff0c;弹性是要考虑的最重要因素之一。当应用程序可以快速从故障中恢复时&#xff0c;它便具有弹性。云原生应用程序通常设计为使用微服务架构&#xff0c;其中每个组件都位于容器中。为了确保Kubernetes托管的应用程序高可用&#xff0…

「offer来了」2种递进学习思维,24道计网题目,保姆级巩固你的计网知识体系

「面试专栏」前端面试之计算机网络篇⚾序言&#x1f3d0;一、基础知识环节1、专栏学习2、书籍学习⚽二、思维导图环节&#x1f3b3;三、OSI七层模型1、OSI模型是什么&#xff1f;2、OSI七层模型遵循原则&#x1f3cf;四、TCP与UDP1、TCP与UDP的区别2、TCP/UDP的优缺点&#xff…

leetcode236. 二叉树的最近公共祖先

一:题目 二:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:/**思路:1.这里我们需要的是从底向上开…