当前位置: 首页 > news >正文

辨析git reset三种模式以及和git revert的区别:回退到指定版本和撤销指定版本的操作

辨析git reset和git revert

  • git revert:撤销指定版本的修改内容
    • 实例介绍
    • 执行 `git revert C`
    • **revert总结**
  • git reset : 回退到指定版本
    • 模式一:`git reset --hard C` (最暴力、最彻底的模式)
    • 模式二:`git reset --mixed C` (默认模式)
    • 模式三:`git reset --soft C` (最温柔的模式)
    • reset总结
  • 总结

git revert:撤销指定版本的修改内容

git revert 不是让的项目“回到”版本C的状态
作用是:创建一个全新的提交,这个新提交的内容,刚好是版本C所做修改的“反向操作”

实例介绍

假设项目是一个故事文件 story.txt,历史如下:

  1. Commit A (初始)

    • 文件内容:
      从前有座山。
      
  2. Commit B (发展)

    • 增加了新的一行。
    • 文件内容:
      从前有座山。
      山里有座庙。
      
  3. Commit C (错误的修改)

    • 画蛇添足,加了一句不该加的话。
    • 文件内容:
      从前有座山。
      山里有座庙。
      【庙被拆了。】  <-- 这是Commit C引入的修改
      
  4. Commit D (后续的工作)

    • 没意识到C的错误,继续往下写。
    • 文件内容:
      从前有座山。
      山里有座庙。
      【庙被拆了。】
      和尚下山了。   <-- 这是Commit D引入的修改
      

现在的项目历史是 A -> B -> C -> D


执行 git revert C

目标:希望撤销“庙被拆了”这句错误的话,但必须保留“和尚下山了”这句有用的后续工作。

  1. 分析Commit C:Git会查看 Commit C 到底做了什么修改。它发现 C 的修改是**“增加了‘庙被拆了。’这一行”**。

  2. 执行反向操作revert 的核心就是做反向操作。既然 C 的操作是“增加”,那么它的反向操作就是**“删除‘庙被拆了。’这一行”**。

  3. 创建新Commit E:Git 会把这个“反向操作”作为一个全新的提交,我们叫它 Commit E。

    • 这个 Commit E 的提交信息通常会自动生成为 “Revert ‘Commit C 的提交信息’”。
    • 这个 Commit E 的修改内容,就是从当前最新版本(D的状态)中,删除 “庙被拆了。” 这一行。

revert之后的结果:

  • 新的项目历史: A -> B -> C -> D -> E (Revert C)
  • 最终的文件内容:
    从前有座山。
    山里有座庙。
    和尚下山了。
    

revert总结

  • 我们没有回到 Commit C 的状态(那会丢失“和尚下山了”)。
  • 我们也没有回到 Commit B 的状态(那同样会丢失“和尚下山了”)。
  • 我们只是在最新的状态(D)基础上,精确地“抵消”掉了 C 所带来的变更,同时完好无损地保留了 D 的变更。

git reset : 回退到指定版本

继续用这个生动的故事例子来解析 git reset C 会发生什么。这就像是坐上了时光机,但时光机有不同的模式,对应着 reset 的三个主要选项:--hard, --mixed (默认), 和 --soft

出发前的状态(和之前一样):

  • 项目历史: A -> B -> C -> D (HEAD指针在这里)
  • 当前文件 story.txt 内容:
    从前有座山。
    山里有座庙。
    【庙被拆了。】
    和尚下山了。
    

现在,我们执行 git reset C。这个操作的核心是:HEAD 指针和当前分支(比如 main)的指针,强行移动到 commit C。这就像是宣布:“官方历史只记录到 C 为止!”

commit D 并没有被立即删除,它只是变成了“孤魂野鬼”,不再被任何分支引用。如果后续没有其他操作,它最终会被Git的垃圾回收机制清理掉。

那么,你的工作区(story.txt 文件)和暂存区会发生什么变化呢?这取决于你使用的模式。


模式一:git reset --hard C (最暴力、最彻底的模式)

这就像是霸道总裁的时光机,不仅回到了过去,还把之后的一切痕迹都抹除了。

  • 操作git reset --hard C

  • 时光机的行为:

    1. 历史指针移动: HEAD 指针从 D 移动回 C。历史记录现在看起来是 A -> B -> C
    2. 暂存区重置: 暂存区(Staging Area)的内容被完全重置,使其与 C 的内容一模一样。
    3. 工作区重置: 你的工作目录(硬盘上的 story.txt 文件)被强制更新,使其内容也与 C 的内容一模一样。
  • 结果:

    • 最终历史: A -> B -> C (HEAD)
    • 最终文件 story.txt 内容:
      从前有座山。
      山里有座庙。
      【庙被拆了。】
      
    • 损失: “和尚下山了”这句在 D 中的修改,彻底消失了,无论是在暂存区还是在你的文件里,都找不到了。这是个有损操作,一定要小心!

模式二:git reset --mixed C (默认模式)

如果你只输入 git reset C,Git默认就是使用 --mixed 模式。这像是时光机把你带回去了,但把你之前写的草稿(工作成果)留在了桌子上。

  • 操作: git reset Cgit reset --mixed C

  • 时光机的行为:

    1. 历史指针移动: HEAD 指针从 D 移动回 C。历史记录现在是 A -> B -> C
    2. 暂存区重置: 暂存区的内容被重置,与 C 的内容保持一致。
    3. 工作区不变: 关键区别! 你的工作目录(story.txt 文件)保持不变,它仍然是 D 操作之后的样子。
  • 结果:

    • 最终历史: A -> B -> C (HEAD)
    • 最终文件 story.txt 内容:
      从前有座山。
      山里有座庙。
      【庙被拆了。】
      和尚下山了。
      
    • git status 的状态: Git会告诉你,你的工作目录和暂存区有差异。它会显示“和尚下山了”这句是未暂存的修改 (unstaged change)
    • 意义: Git帮你撤销了 commit D 这个提交行为,但保留了 D 的代码修改。你可以检查这些修改,决定是重新提交、修改后再提交,还是彻底丢弃 (git checkout -- .)。

模式三:git reset --soft C (最温柔的模式)

这就像是时光机仅仅移动了书签,而书的内容和你的草稿都原封不动。

  • 操作: git reset --soft C

  • 时光机的行为:

    1. 历史指针移动: 这是它唯一做的事情! HEAD 指针从 D 移动回 C。历史记录现在是 A -> B -> C
    2. 暂存区不变: 暂存区的内容保持不变,和 D 操作后一样。
    3. 工作区不变: 你的工作目录(story.txt 文件)也保持不变
  • 结果:

    • 最终历史: A -> B -> C (HEAD)
    • 最终文件 story.txt 内容:
      从前有座山。
      山里有座庙。
      【庙被拆了。】
      和尚下山了。
      
    • git status 的状态: Git会告诉你,你有已暂存的修改 (staged changes),这个修改就是 D 所做的 “和尚下山了”。
    • 意义: 这个模式非常适合用于“合并提交”。比如你发现 CD 两个提交其实应该合成一个,你就可以 reset --soft B,然后把 CD 的所有修改一次性重新提交。

reset总结

操作 (git reset C)历史指针 (HEAD)暂存区 (Staging Area)工作目录 (文件)主要用途
--hard回到 C变成 C 的样子变成 C 的样子彻底丢弃 C 之后的所有提交和修改,慎用!
--mixed (默认)回到 C变成 C 的样子保持不变撤销提交但保留代码修改,可以重新整理。
--soft回到 C保持不变保持不变合并多个提交,或只是想修改最后一次提交的信息。

所以,git reset C 确实是“回到过去”,但“回到过去”之后现场会变成什么样,取决于你选择的时光机模式。这与 git revert 那种“向前走,做反向操作来弥补”的思路,有着本质的区别。

总结

git revert 像是在故事的最新结尾(“和尚下山了”之后)补写了一个新章节,内容是“哦,之前说的庙被拆了是假的”,从而优雅地修正了错误,保留了所有历史。

git reset 则是直接乘坐时光机回到“庙被拆了”那一刻,然后粗暴地撕掉了后面“和尚下山了”这一页历史,让故事看起来就像从未发生过一样。

http://www.lryc.cn/news/589496.html

相关文章:

  • Python:消息队列(RabbitMQ)应用开发实践
  • BlueLotus XSS管理后台使用指南
  • 数据结构自学Day7-- 二叉树
  • 自增主键为什么不是连续的?
  • 策略设计模式分析
  • Git Bash 实战操作全解析:从初始化到版本管理的每一步细节
  • Spring Boot 启动原理揭秘:从 main 方法到自动装配
  • c#进阶之数据结构(字符串篇)----String
  • HTTP常见误区
  • 跨平台移动开发技术深度分析:uni-app、React Native与Flutter的迁移成本、性能、场景与前景
  • 【网络安全】大型语言模型(LLMs)及其应用的红队演练指南
  • 物联网系统中MQTT设备数据的保存方法
  • 闲庭信步使用图像验证平台加速FPGA的开发:第十七课——图像高斯滤波的FPGA实现
  • 基于Langchain4j开发AI编程助手
  • 无人机GPS定位系统核心技术解析
  • 图像的读入、显示、保存和图像文件显示
  • 笔试——Day9
  • IMU 能为无人机提供什么数据?
  • 北京-4年功能测试2年空窗-报培训班学测开-第五十一天
  • 快速通关二叉树秘籍(下)
  • Rocky Linux 9 源码包安装php8
  • ChatTongyi × LangChain:开启多模态AI应用创新之门
  • 共射级放大电路的频率响应Multisim电路仿真——硬件工程师笔记
  • 50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | DoubleClickHeart(双击爱心)
  • [设计模式]C++单例模式的几种写法以及通用模板
  • Kubernetes 架构原理与集群环境部署
  • 降本增效!自动化UI测试平台TestComplete并行测试亮点
  • 2025最新国产用例管理工具评测:Gitee Test、禅道、蓝凌测试、TestOps 哪家更懂研发协同?
  • ESLint 除了在packages.json还能在哪里配置?
  • 实测两款效率工具:驾考刷题和证件照处理的免费方案