Git | git revert命令详解

news2025/1/13 14:15:08

关注:CodingTechWork

引言

  Git 是一个强大的版本控制工具,广泛应用于现代软件开发中。它为开发人员提供了多种功能来管理代码、协作开发和版本控制。在 Git 中,有时我们需要撤销或回退某些提交,而git revert 是一个非常有用的命令。与git reset等命令不同,git revert能够通过创建新的提交来撤销历史提交,保证项目历史的完整性。
  在本篇文章中,我们将详细介绍 Git 中 git revert 的使用方式、工作原理、实战示例以及一些注意事项。

git revert介绍

  git revert用于撤销一个已经提交到 Git 仓库的更改。不同于git resetgit revert会通过创建一个新的提交“反转”指定提交的内容,而不会改变历史提交的记录。因此,git revert 是一种更安全的回退操作,适用于团队合作中,因为它不会影响历史提交的结构。

git revert 的工作原理

git revert原理:

  1. 生成新的提交git revert 会创建一个新的提交,内容是要撤销的提交的“反操作”。也就是说,git revert 会通过相反的改动来撤销指定提交的更改。例如,如果原来提交中增加了某些代码行,git revert会通过删除这些行来撤销该提交。
  2. 保持项目历史的完整性:与git reset可能修改项目历史不同,git revert不会删除任何提交,而是通过新的提交来记录撤销操作,从而保证了版本历史的完整性。这使得它特别适用于公共分支(如 mastermain 分支)。

执行步骤

  1. Git 会根据指定的提交,计算出需要反向操作的更改。
  2. 创建一个新的提交,将这些反向更改应用到当前工作区。
  3. 你可以选择是否修改提交信息(默认信息为“Revert ”)。
  4. 提交反向更改,新的提交将插入到当前分支历史中。

git revert 的常见用法

撤销单个提交

假设我们在分支上做了多次提交,其中有一个提交包含了不需要的更改。使用 git log 查看提交历史:

git log --oneline

输出结果可能是这样的:

a1b2c3d (HEAD -> master) Added new feature
a1342cf Fixed bug in feature X
d4e5f6g Added README file

如果你想撤销某个特定提交,可以直接指定该提交的哈希值(commit hash)来执行git revert

git revert <commit-hash>

例如,如果你想撤销提交 a1b2c3d,可以运行以下命令:

git revert a1b2c3d

Git 会自动生成一个新的提交,反向应用 a1b2c3d 提交中的修改,并提示你输入提交消息。

撤销多个提交

如果你需要撤销一系列提交,可以使用 git revert-n--no-commit选项,它会将所有反向更改暂时保存在暂存区中,但不会立即提交。你可以手动编辑这些更改,并最终一起提交。

git revert -n <commit-hash1>^..<commit-hash2>
  • <commit-hash1>^..<commit-hash2> 表示从 <commit-hash1> <commit-hash2> 的提交范围。
  • ^表示选择 <commit-hash1> 的父提交,因此是一个范围。
    举个例子,撤销从提交 a1b2c3d 到提交 d4e5f6g 的所有修改:
git revert -n a1b2c3d^..d4e5f6g

执行后,所有变更会暂时存放在暂存区,等待提交。

举个例子:

假设你有以下的提交历史:

* abc1234 (HEAD -> master) Merge feature-branch into master
* d7e6b2d (feature-branch) Add new feature
* 3a6c0f2 (master) Initial commit

其中,abc1234 是一个合并提交,feature-branch 被合并进了 master。现在,你想撤销这个合并提交,并希望保留 master 分支的变更,因此使用命令:

git revert -m 1 abc1234

这个命令会创建一个新的提交,撤销合并操作中的更改,实际上它将会 恢复到 abc1234 合并之前的状态,但历史记录仍会保留合并提交。新的提交将会与 abc1234 之后的提交一起继续保留在历史中。
为什么需要 -m 参数?
合并提交有多个父提交,Git 需要知道你希望保留哪个父提交的内容。-m 1表示选择第一个父提交作为保留的版本,通常是主分支的版本。如果你使用 -m ,那么 Git 将选择第二个父提交,通常是被合并进来的分支的版本。

使用交互式 git revert

当你想撤销多个提交时,有时会遇到冲突,Git 会提示你进行冲突解决。git revert 会一个一个地撤销指定的提交,并且如果有冲突,Git 会停止并让你解决冲突。解决冲突后,你可以继续操作。
解决冲突后运行:

git revert --continue

如果你决定取消当前的撤销操作,可以使用:

git revert --abort

撤销合并提交

有时,你可能会遇到需要撤销合并提交的场景。合并提交具有特殊的结构,因此在执行 git revert 时需要额外小心。假设你有一个合并提交 abc1234,可以使用以下命令来撤销它:

git revert -m 1 abc1234

-m 1: 指定了合并提交的“主父提交”(通常是主分支)。-m后面的数字表示选择哪个父提交作为保留版本。
通过 git revert -m,Git 会根据指定的父提交创建一个新的提交来撤销合并操作。

强制跳过某次提交的提交信息编辑

在某些场景下,你可能希望跳过git revert操作中的提交信息编辑过程。可以通过--no-edit选项来跳过:

git revert --no-edit f7e8b2c

这个命令会直接执行`git revert操作,但不会弹出编辑器让你修改提交信息,而是使用默认的信息。

实战示例:撤销错误提交

假设你正在一个开发分支feature/login上工作,发现最近的一个提交引入了一个错误。你需要撤销该错误提交,但又不想修改历史提交(即不使用 git reset)。这时,git revert就非常适合。

查看提交历史

首先,我们查看最近的提交历史,找到要撤销的提交。

git log --oneline

输出可能是这样的:

a1b2c3d Add login feature
d4e5f6g Fix UI bug
h7i8j9k Update documentation

假设提交 a1b2c3d 引入了一个错误,我们需要撤销它。

执行 git revert

接下来,使用 git revert 撤销该提交:

git revert a1b2c3d

Git 会自动生成一个新的提交,撤销 a1b2c3d 中的所有更改。

解决冲突

如果 Git 在应用反向更改时发生了冲突,Git 会提示你进行冲突解决。你需要打开冲突文件,手动解决冲突,然后执行:

git add <conflicted-file>
git revert --continue

完成提交

最终,提交就会成功创建,撤销操作也完成了。可以通过 git log 查看新的提交记录,确认撤销操作已经生效。

git log --oneline

输出可能是:

f7g8h9i Revert "Add login feature"
a1b2c3d Add login feature
d4e5f6g Fix UI bug
h7i8j9k Update documentation

着重讲一下git revert -m

git提交历史模拟

假设我们有以下的 Git 历史:

* abc1234 (HEAD -> master) Merge feat02-branch into master
* def5678 (feat02-branch) Add feature 2
* ghi2345 (feat01-branch) Add feature 1
* jkl3456 (master) Initial commit

在这个例子中:

  • abc1234 是合并提交,它将 feat02-branch 合并到 master。
  • def5678 是 feat02-branch 上的提交,它增加了 feat02-branch 的功能。
  • ghi2345 是 feat01-branch 上的提交,它增加了 feat01-branch 的功能。
  • jkl3456 是 master 上的初始提交。

合并提交 abc1234 是一个合并提交,它有两个父提交:

  1. jkl3456(master 分支的提交)
  2. def5678(feat02-branch 分支的提交)

git revert -m 1 abc1234

git revert -m 1 abc1234表示撤销合并提交 abc1234,并保留第一个父提交(master 分支的提交)。即,撤销 feat02-branch 的更改并保留 master 分支的更改。
执行这个命令后,Git 会生成一个新的提交,撤销合并 feat02-branch 到 master 的操作,而不影响 feat01-branch 和 master 之间的关系。
命令

git revert -m 1 abc1234

git revert -m 2 abc1234

git revert -m 2 abc1234 表示撤销合并提交 abc1234,并保留第二个父提交(feat02-branch 分支的提交)。即,撤销 master 上的更改并保留 feat02-branch 的更改。
执行这个命令后,Git 会生成一个新的提交,撤销 master 分支的更改,同时保留 feat02-branch 的更改。
命令

git revert -m 2 abc1234

git revert -m 3 abc1234

git revert -m 3是一个特殊情况,适用于三方合并,通常会有多个父提交。例如,如果合并提交涉及 feat01-branch、feat02-branch 和 master 三个分支,那么可以使用 -m 3 来指定第三个父提交。然而,在我们这个例子中,由于合并提交 abc1234 只涉及 master 和 feat02-branch 两个父提交,因此 -m 3 不适用。假设有三方合并的历史如下:

*   abcd1234 (HEAD -> master) Merge branch 'feat01-branch' and 'feat02-branch'
|\
| * 12345678 (feat01-branch) Commit in feat01-branch
* | 87654321 (feat02-branch) Commit in feat02-branch
|/
*   11223344 Initial commit in master

在这个示例中:

  • abcd1234 是合并提交,具有 3 个父提交:
    • 父提交 1:master(在 abcd1234 之前的提交)。
    • 父提交 2:feat01-branch(合并进来的一个分支)。
    • 父提交 3:feat02-branch(合并进来的另一个分支)。

git revert -m 3 abcd1234使用-m 3时,Git 会选择第三个父提交作为基准(在这个例子中是 feat02-branch),并撤销合并提交中的更改。也就是说,撤销的合并提交会回滚 master 和 feat01-branch 的更改,但保留 feat02-branch 上的内容。

git revert -m 3 abcd1234

效果:Git 会撤销 abcd1234 的合并,回滚 master 和 feat01-branch 上的修改。结果是保留了 feat02-branch 上的修改,并回滚了 master 和 feat01-branch 的修改。

-m 总结

  • git revert -m 1 <commit>:撤销合并提交,保留第一个父提交的变更。
  • git revert -m 2 <commit>:撤销合并提交,保留第二个父提交的变更。
  • git revert -m 3 <commit>:撤销合并提交,保留第三个父提交的变更(适用于三方合并)。

git revert 与 git reset 的比较

git revert vs git reset

git revert

  • 用于撤销已经提交的内容。
  • 保持历史提交的完整性,不会改变提交记录。
  • 适用于公共分支,避免影响其他开发人员的工作。

git reset

  • 用于重置当前分支的指针,可以回退到某个历史提交。
  • 会改变提交历史,可能导致丢失更改。
  • 适用于个人分支或本地仓库的操作。

哪个更适合团队合作?

在团队协作中,通常建议使用git revert,因为它不会重写历史,而是创建一个新的提交,撤销先前的更改。这样可以保证团队成员之间的协作历史不受干扰。

注意事项

  1. 小心使用git revertgit revert会创建新的提交,因此如果你频繁地进行撤销操作,可能会导致提交历史变得冗长。在撤销多个提交时,可以考虑将多个撤销操作合并到一次提交中,以保持清晰的历史记录。
  2. 处理冲突:当你撤销提交时,可能会遇到文件冲突。务必认真解决冲突,以确保撤销操作正确执行。
  3. 避免在已经发布的分支中使用 git resetgit reset会重写历史,这会给协作带来麻烦,而git revert保持了历史的连贯性,因此在公共分支中,推荐使用git revert

总结

  git revert是 Git 中撤销历史提交的强大工具,能够通过创建新的提交来撤销指定的更改,保持项目历史的完整性,避免重写历史,适用于团队合作中的常见场景。通过理解和掌握git revert,开发人员可以更加灵活和安全地管理代码历史,并在出现错误时轻松回退。

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

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

相关文章

RAID储存技术

RAID独立磁盘冗余技术是一种把2个或者多个HDD或SSD合并为一个协调的存储单元或列阵&#xff0c;从而预防数据丢失的技术&#xff0c;其最早由加州大学伯克利分校的计算机科学家David Patterson、Garth Gibson和Randy Katz在1987年提出。他们的研究论文“关于RAID的论证”提出了…

Java Web开发基础:HTML的深度解析与应用

文章目录 前言&#x1f30d;一.B/S 软件开发架构简述&#x1f30d;二.HTML 介绍❄️2.1 官方文档❄️2.2 网页的组成❄️2.3 HTML 是什么❄️2.4html基本结构 &#x1f30d;三.HTML标签1.html 的标签/元素-说明2. html 标签注意事项和细节3.font 字体标签4.标题标签5.超链接标签…

使用 WPF 和 C# 绘制图形

绘图困难 此示例展示了如何在 WPF 和 C# 中绘制图形。绘制图形总是很棘手&#xff0c;因为您通常需要在至少两个不同的坐标系中工作。首先&#xff0c;您要为图形使用世界坐标。例如&#xff0c;您可能希望 X 值的范围为 2000 年至 2020 年&#xff0c;Y 值的范围为 10,000 美元…

年度技术突破奖|中兴微电子引领汽车芯片新变革

随着以中央计算区域控制为代表的新一代整车电子架构逐步成为行业主流&#xff0c;车企在电动化与智能化之后&#xff0c;正迎来以架构创新为核心的新一轮技术竞争。中央计算SoC&#xff0c;作为支撑智驾和智舱高算力需求的核心组件&#xff0c;已成为汽车电子市场的重要新增量。…

【JVM-2.3】深入解析JVisualVM:Java性能监控与调优利器

在Java应用的开发和运维过程中&#xff0c;性能监控与调优是不可或缺的环节。无论是排查内存泄漏、分析CPU瓶颈&#xff0c;还是优化线程使用&#xff0c;开发者都需要借助一些强大的工具来辅助诊断。JVisualVM 正是这样一款由Oracle提供的免费工具&#xff0c;它集成了多种性能…

filestream安装使用全套+filebeat的模块用法

1 filestream介绍 官方宣布&#xff1a;输入类型为log在filebeat7.16版本已经弃用了 Filestream 是 Filebeat 中的一种 输入类型&#xff08;Input&#xff09;&#xff0c;用于处理日志文件的读取。它是为了取代 Filebeat 中传统的 log 输入&#xff08;Input&#xff09;设…

超燃预告!Origin百图绘制系列即将登场

Hello&#xff0c;大家好 这里是练习时长两年半的菜狗~ 持续更新各种竞赛&#xff0c;科研&#xff0c;保研&#xff0c;学习干货ing 回想刚开始打比赛那会&#xff0c;啥都不懂&#xff0c;就从用 Excel 画图起步&#xff0c;绘制的图形实在太难看。后来运用 Matlab&#xf…

八、系统托盘与配置面板

没有人会把你变得越来越好&#xff0c;时间和经历只是陪衬。 支撑你变得越来越好的&#xff0c;是你自己坚强的意志、修养、品行、以及不断的反思和经验。 人生最好的贵人&#xff0c;就是努力向上的自己。 一、系统托盘 1、资源文件夹 新建资源文件夹&#xff0c;我们需要把…

uniapp 之 uni-forms校验提示【提交的字段[‘xxx‘]在数据库中并不存在】解决方案

目录 场景问题代码结果问题剖析解决方案 场景 uni-forms官方组件地址 使用uniapp官方提供的组件&#xff0c;某个表单需求&#xff0c;单位性质字段如果是高校&#xff0c;那么工作单位则是高校的下拉选择格式&#xff0c;单位性质如果是其他的类型&#xff0c;工作单位则是手动…

Java面试核心知识4

公平锁与非公平锁 公平锁&#xff08;Fair&#xff09; 加锁前检查是否有排队等待的线程&#xff0c;优先排队等待的线程&#xff0c;先来先得 非公平锁&#xff08;Nonfair&#xff09; 加锁时不考虑排队等待问题&#xff0c;直接尝试获取锁&#xff0c;获取不到自动到队尾…

基于 SSH 的任务调度系统

文末附有完整项目代码 在当今科技飞速发展的时代&#xff0c;任务调度系统的重要性日益凸显。本文将详细介绍一个基于 SSH&#xff08;SpringStruts2Hibernate&#xff09;的任务调度系统的设计与实现。 一、系统概述 本系统旨在改变传统人工任务调度方式&#xff0c;通过计算…

我的128天创作之路:回顾与展望

大家好呀&#xff01;今天来和你们分享一下我的创作历程&#x1f601;。 一、机缘 最开始创作呢&#xff0c;是因为在学习 C 的 STL 时&#xff0c;像 string、list、vector 这些模板可把我折腾得够呛&#xff0c;但也让我学到了超多东西&#xff01;我就想&#xff0c;要是把我…

性能测试工具Jmeter中的FTP脚本开发

FTP文件传输协议是TCP/IP协议组织中的常用协议之一&#xff0c;主要用在internet上双向传输文件。FTP协议具有客户端和服务器端两个部分组成部分&#xff0c;具有上传与下载两种功能。Jmeter也提供了FTP请求的测试支持&#xff0c;实现了上传和下载功能测试。 对于上图的FTP请求…

【C++】string的关系运算与比较分析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;基础知识&#xff1a;C 中的 string 关系运算器1. 关系运算器概述2. 字符串比较的本质 &#x1f4af;代码解析与扩展代码例一&#xff1a;相等比较代码解析输出 代码例二&a…

mysql本地安装和pycharm链接数据库操作

MySQL本地安装和相关操作 Python相关&#xff1a;基础、函数、数据类型、面向、模块。 前端开发&#xff1a;HTML、CSS、JavaScript、jQuery。【静态页面】 Java前端&#xff1b; Python前端&#xff1b; Go前端 -> 【动态页面】直观&#xff1a; 静态&#xff0c;写死了…

深度学习|表示学习|一个神经元可以干什么|02

如是我闻&#xff1a; 如果我们只有一个神经元&#xff08;即一个单一的线性或非线性函数&#xff09;&#xff0c;仍然可以完成一些简单的任务。以下是一个神经元可以实现的功能和应用&#xff1a; 1. 实现简单的线性分类 输入&#xff1a;一组特征向量 x x x 输出&#xff…

HTB:Paper[WriteUP]

目录 连接至HTB服务器并启动靶机 信息收集 使用rustscan对靶机TCP端口进行开放扫描 将靶机TCP开放端口号提取并保存 使用nmap对靶机TCP开放端口进行脚本、服务扫描 使用nmap对靶机TCP开放端口进行漏洞、系统扫描 使用nmap对靶机常用UDP端口进行开放扫描 对靶机进行子域…

做一个 简单的Django 《股票自选助手》显示 用akshare 库(A股数据获取)

图&#xff1a; 股票自选助手 这是一个基于 Django 开发的 A 股自选股票信息查看系统。系统使用 akshare 库获取实时股票数据&#xff0c;支持添加、删除和更新股票信息。 功能特点 支持添加自选股票实时显示股票价格和涨跌幅一键更新所有股票数据支持删除不需要的股票使用中…

Unity + Firebase + GoogleSignIn 导入问题

我目前使用 Unity版本&#xff1a;2021.3.33f1 JDK版本为&#xff1a;1.8 Gradle 版本为&#xff1a;6.1.1 Firebase 版本: 9.6.0 Google Sign In 版本为&#xff1a; 1.0.1 问题1 &#xff1a;手机点击登录报错 apk转化成zip&#xff0c;解压&#xff0c;看到/lib/armeabi-v…

Django学习笔记之数据库(一)

文章目录 安装一、数据库配置二、基本操作步骤1.增加2.查看3.排序4.更新5.删除数据 三、一对多&#xff0c;多对多&#xff0c;一对一1.一对多1.一对一1.多对多 四、查询操作五、聚合操作六、F和Q操作 安装 首先就是安装Mysql和Navicat。 一、数据库配置 其实整个就是连接前端…