Git回滚详解

news2024/11/20 19:45:01

文章目录

    • git restore
      • 撤销工作区文件更改
      • 撤销暂存区文件更改
    • git checkout
    • git revert
      • 冲突解决
      • 具体操作
    • git reset
      • reset 的作用
      • 第 1 步:移动 HEAD(--soft)
      • 第 2 步:更新暂存区(--mixed)
      • 第 3 步:更新工作区(--hard)
      • 顺序总结
      • reset与revert的区别

此文在阅读前需要有一定的git命令基础,若基础尚未掌握,建议先阅读这篇文章Git命令播报详版

在利用git协作过程中,经常需要进行代码的撤销操作,这个行为可能发生在工作区,暂存区或者仓库区(或版本库)。

我们先讨论在工作区与暂存区发生的撤销行为,这里会有两个命令提供帮助,git restoregit checkout

后面我们会讨论在仓库区发生的撤销行为,这里同样会有两个命令提供帮助,git resetgit revert

git restore

git restore主要是在工作区与暂存区之间进行撤销操作。

撤销工作区文件更改

我们在工作区修改了某个文件,然后我们想放弃此次修改,那么可以使用git restore pathspec

修改文件后,我们查看文件状态,可以看到文件状态已经变化

git status -s

输出:
 M README.md

撤销修改后查看状态,可看到工作区已经干净

git restore README.md 

git status

输出:
...
nothing to commit, working tree clean

如果我们同时修改了多个文件,想全部撤销,则可以执行git restore .命令

结论:git restore pathspec指令使得在工作空间但是不在暂存区的文件撤销更改(内容恢复到没修改之前的状态)。

撤销暂存区文件更改

git restore --staged pathspec指令将暂存区的文件撤回到工作区,但不会更改文件的内容。

我们将某个文件进行修改并添加到暂存区,查看状态

git status 

输出:
...
Changes to be committed:
  ...
        modified:   README.md

进行撤销后,再进行状态的查看

git restore --staged README.md  

git status

输出:
...
Changes not staged for commit:
  ...
        modified:   README.md
...

如果我们想撤销暂存区的所有文件改动到工作区,则可以执行git restore --staged .命令

从上面我们能看出git restore命令的局限性:

  1. 它无法直接对暂存区的文件撤销到原始未修改状态。
  2. 也没有能力直接将工作区与暂存区文件同时撤销到原始未修改状态。

接下来我们可以看看git checkout的表现。

git checkout

git checkout [<commit>] [--] <filePath>语法:

  • checkout命令主要是覆盖工作区(如果<commit>不省略,也会替换暂存区中相应的文件),且不会改变 HEAD 指针。
  • <commit> 是可选项,如果省略则默认是从暂存区检出。这和下面将要讲述的 git reset重置大不相同,重置的默认值是HEAD,即等于git reset HEAD
  • 为了避免路径<filePath>和引用(或者提交)<commit> 同名而冲突,可以在<filePath>前用两个连续的短线减号作为分隔。如git checkout HEAD -- <filePath>

语法示例:

  • 当执行 git checkout . 或者 git checkout <filePath> 命令时,会用暂存区全部或指定的文件替换工作区的文件。这个操作很危险,会清除工作区中改动。
  • 当执行 git checkout HEAD . 或者 git checkout HEAD <filePath> 命令时,会用 HEAD 提交的全部或者部分文件替换暂存区以及工作区中的文件。这个命令也是极具危险性的,因为不但会清除工作区中的改动,也会清除暂存区中的改动。

git revert

git revert -n commit-id:只会反做commit-id对应的内容,然后重新commit一个信息,不会影响其他的commit内容

比如,我们commit了三个版本(版本一、版本二、 版本三),突然发现版本二不行(如:有bug),想要撤销版本二,但又不想影响撤销版本三的提交,就可以用 git revert 命令来反做版本二,生成新的版本四,这个版本四里会保留版本三的东西,但撤销了版本二的东西。如下图所示:

git revert -n commit-idA..commit-idB:反做commit-idA到commit-idB之间的所有commit

注意:使用-n是应为revert后,需要重新提交一个commit信息,然后在推送。如果不使用-n,指令后会弹出编辑器用于编辑提交信息

适用场景:如果我们想撤销之前的某一版本,但是又想保留该目标版本后面的版本,记录下这整个版本变动流程,就可以用这种方法。

冲突解决

git revert操作过程中,冲突难以避免,下面有几种解决方式

  • git revert --abort:冲突发生后,当前的操作会回到指令执行之前的样子,回到原始的状态,相当于什么事没有发生
  • git revert --quit:冲突发生后,从反做操作行为中退出,该指令会保留文件冲突
  • git revert --skip:冲突发生后,跳过此次反做操作
  • git revert --continue:冲突发生后,解决冲突并add后,执行该命令,会继续之前的操作流程
  • 冲突发生后,也可以手动操作。
      git add .
      git commit -m "提交的信息"
      git push
    

具体操作

先查看历史提交记录

git log --oneline

输出:
0681044 (HEAD -> dev, origin/dev) v3
3a854db v2
fc00739 v1
8785cc6 dev提交
709627d Initial commit

对提交信息为v1的进行反做

git revert -n fc00739

输出:
Auto-merging README.en.md
CONFLICT (content): Merge conflict in README.en.md
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: could not revert fc00739... v1
...

出现冲突,进行修改,重新添加文件到暂存区,并进行提交

git add .

git revert --continue

输出:
hint: Waiting for your editor to close the file... unix2dos: converting file D:/project/personal/gittestproject/.git/COMMIT_EDITMSG to DOS format...
dos2unix: converting file D:/project/personal/gittestproject/.git/COMMIT_EDITMSG to Unix format...
[dev 972bfce] Revert "v2"
 2 files changed, 2 insertions(+), 2 deletions(-)

推送到远程

git push

查看提交历史记录

git log --oneline 

输出:
77adce6 (HEAD -> dev, origin/dev) Revert "v1"
0681044 v3
3a854db v2
fc00739 v1
8785cc6 dev提交
709627d Initial commit

git reset

先通过举个例子,来一个感性的认识。下面这两条命令让 hotfix 分支向后回退两个提交。

git checkout hotfix
git reset HEAD~2

仓库区HEAD指针指向当前分支最新提交,回退两个提交后,hotfix 分支末端的两个提交现在变成了孤儿提交,如果你的提交还没有提交到远程,可以如上所示,直接用git reset撤销这些提交。

若之前提交已经提交到远程,使用git reset进行回退后,再使用git push提交更改,此时会报错,因为我们本地库HEAD指向的版本比远程库的要旧。所以我们要用git push -f强制推上去,就可以了,那么回退就成功了!

适用场景: 如果想恢复到之前某个提交的版本,且那个版本之后提交的版本我们都不要了,就可以用这种方法。

reset 的作用

为了演示下面这些例子,假设我们修改了 file.txt 文件并第三次提交它。 现在的历史看起来是这样的:

现在,假设我们运行git reset HEAD~(后面可能会跟不同的参数)。

第 1 步:移动 HEAD(–soft)

reset 做的第一件事是移动所在分支 HEAD 的指向。

运行 git reset HEAD~ –-soft 将会指向 9e5e6a4,这与checkout通过切换分支来改变 HEAD 自身不同。

结合上图,我们理解一下发生的事情:它本质上是撤销了上一次 git commit 命令。 当你在运行 git commit 时,Git 会创建一个新的提交,并移动当前所在分支 HEAD 的指向,使之指向最新提交。 当你将它 reset --softHEAD~HEAD 的父结点)时,其实就是把该分支移回原来的位置,而不会改变暂存区和工作区。

具体表现是:撤销上一次git commit的文件,将其放在暂存区,并与暂存区文件进行合并(如果有相同文件改动的话),工作区没有改变

第 2 步:更新暂存区(–mixed)

接下来,git reset HEAD~ –-mixed 会用 HEAD 指向的当前快照的内容来更新暂存区。

这也是默认行为,即可以忽略选项,git reset HEAD~

现在再看一眼上图,理解一下发生的事情:它依然会撤销一上次提交,但还会取消所有暂存。 于是,我们回滚到了所有 git addgit commit 的命令执行之前。

具体表现是:撤销上一次git commit的文件,并取消所有暂存区文件,将其与工作区文件进行合并(如果有相同文件改动的话)

第 3 步:更新工作区(–hard)

如果使用 –-hard 选项,git reset HEAD~ --hard 要做的的第三件事情就是让工作区看起来像暂存区。

现在让我们回想一下刚才发生的事情:你撤销了最后的提交(git commit )、git add 和工作区中的所有工作。

必须注意,–hard 标记是 reset 命令唯一的危险用法,它也是 Git 会真正地销毁数据的仅有的几个操作之一。其他任何形式的 reset 调用都可以轻松撤消,但是 –hard 选项不能,因为它强制覆盖了工作区中的文件。

具体表现是:撤销暂存区与工作区所有文件改动

顺序总结

reset 命令会以特定的顺序重写这三棵树,在你指定以下选项时停止:

  1. 移动 HEAD 指向的分支 (若指定了 --soft,则到此停止)
  2. 重置 index 以便和 HEAD 相匹配 (若未指定,或指定 --mixed,则到此停止)
  3. 使工作区看起来像暂存区 (若指定 --hard

reset与revert的区别

  • git reset 是回滚到对应的commit-id,相当于是删除了commit-id以后的所有的提交,并且不会产生新的commit-id记录,如果要推送到远程服务器的话,需要强制推送-f
  • git revert 是反做撤销其中的commit-id,然后重新生成一个commit-id。本身不会对其他的提交commit-id产生影响,如果要推送到远程服务器的话,就是普通的操作git push就好了

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

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

相关文章

如何写好英文论文中的句子?(下)

1 前情提要 大家先看完上一篇文章如何写好英文论文中的句子&#xff1f;&#xff08;上&#xff09;&#xff0c;再接着往下翻。 10 先说名词&#xff0c;再用代词&#xff08;it、they&#xff09;指代该名词 11 否定词放在句子开头附近 12 否定词的正确位置&#xff1a;助动…

消息通知之系统层事件发布相关流程

前言 Openharmony 3.1Release中存在消息通知的处理&#xff0c;消息通知包括系统层事件发布、消息订阅、消息投递与处理&#xff0c;为了开发者能够熟悉消息的处理流程&#xff0c;本篇文章主要介绍系统层事件发布的相关流程。 整体流程 代码流程 发布消息 { eventAction)w…

自定义颜色编辑选取对话框

一、简介 Qt中已经有一些封装好的对话框&#xff0c;比如QMessageBox、QColorDialog等&#xff0c;使用起来快捷方便&#xff0c;但缺点是我们无法为它们自定义样式&#xff0c;所以可能难以“融入”我们的项目。既然如此&#xff0c;那就自己做一个把。抱着这样的想法&#x…

Android SELinux安全机制与权限管理那些事

文章目录 前言权限管理系统应用特权应用历史漏洞广播的保护机制CVE-2020-0391 SELinux 前言 在 Android 漏洞挖掘和安全研究过程中&#xff0c;不可避免地会涉及到跟 Android SELinux 安全机制打交道&#xff0c;比如当你手握一个 System 应用的路径穿越的漏洞的时候想去覆写其…

DS:基于鸢尾花数据集利用多种数据降维技术(PCA、SVD、MDS、LDA、T-SNE)实现三维可视化

DS&#xff1a;基于鸢尾花数据集利用多种数据降维技术(PCA、SVD、MDS、LDA、T-SNE)实现三维可视化 目录 基于鸢尾花数据集利用多种数据降维技术(PCA、SVD、MDS、LDA、T-SNE)实现三维可视化 # 1、加载示例数据集&#xff08;鸢尾花数据集&#xff09; # 2、数据预处理 # T1、…

媒体专访是品牌初创阶段宣传的重要手段

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 很早以前&#xff0c;有位前辈跟我讲&#xff0c;人的成功分两种&#xff0c;一种是借助平台成功&#xff0c;一种是自己创业成功&#xff0c; 前者成功的概率很大&#xff0c;只需要选好…

【5.18】二、黑盒测试方法—因果图与决策表法

目录 2.3 因果图与决策表法 2.3.1 因果图设计法 2.3.2 决策表 2.3.3 实例&#xff1a;三角形决策表 2.3.4 实例&#xff1a;工资发放决策表 2.3 因果图与决策表法 等价类划分法与边界值分析法主要侧重于输入条件&#xff0c;却没有考虑这些输入之间的关系&#xff0c;如…

单链表和双向链表如何执行删除操作

在实际的软件开发中&#xff0c;从链表中删除一个数据无外乎这两种情况&#xff1a; 删除结点中“值等于某个给定值”的结点&#xff1b;删除给定指针指向的结点。 1.从头结点开始一个一个依次遍历对比&#xff0c;直到找到值等于给定值的结点&#xff0c;然后再通过我前面讲…

LeetCode高频算法刷题记录4

文章目录 1. 二叉树的最近公共祖先【中等】1.1 题目描述1.2 解题思路1.3 代码实现 2. 全排列【中等】2.1 题目描述2.2 解题思路2.3 代码实现 3. 相交链表【简单】3.1 题目描述3.2 解题思路3.3 代码实现 4. 合并 K 个升序链表【困难】4.1 题目描述4.2 解题思路4.3 代码实现 5. 环…

chatgpt赋能Python-python3_4怎么下载

Python3.4的下载和安装 Python是一种流行的编程语言&#xff0c;它被广泛用于算法学习、数据分析和网站开发等领域。Python3.4是Python编程语言的一个版本&#xff0c;它在性能和功能方面都得到了改进。如果你希望学习Python3.4或者使用它开发项目&#xff0c;那么你需要下载并…

Jetpack Compose中的附带效应简介及使用

前言 附带效应是指LaunchedEffect、DisposableEffect、rememberCoroutineScope、rememberUpdatedState、produceState 、derivedStateOf的使用。附带效应这4个字在google官方文档上的表达与解释挺让人难以理解的。其实个人认为准确的描述应该是外部产生的数据向Compose状态作用…

chatgpt赋能Python-python3_8_1怎么用

Python3.8.1使用指南&#xff1a;让您的编程更加高效 Python是一种流行的高级编程语言&#xff0c;它以简洁明了的语法和丰富的库而著称。如果您是一名新手或有经验的程序员&#xff0c;Python都是一个很好的选择。在Python3.8.1中&#xff0c;新的功能和改进将进一步提高Pyth…

chatgpt赋能Python-python2的n次方程序

Python2的N次方程序&#xff1a;一个实用的编程工具 Python2是广泛使用的编程语言之一&#xff0c;它是一种强大且灵活的开源语言&#xff0c;被广泛应用于科学计算、数据分析、Web开发等领域。在Python2中&#xff0c;N次方程序是一种非常基础的程序&#xff0c;但是它在实际…

二叉树的基本认识(一)

要了解二叉树&#xff0c;就必然要知道什么是树&#xff0c;树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的…

C++类模板的具体化

目录 分类 代码 分析 一、类模板 一&#xff09;代码 二&#xff09;注意事项 三&#xff09;运行结果 二、完全具体化的模板类 一&#xff09;代码 二&#xff09;注意事项 三&#xff09;执行结果 三、部分具体化的模板类 一&#xff09;代码 二&#xff09;注…

【研发工具】Yapi接口管理平台内网Centos8下搭建

1 环境依赖安装 环境要求 nodejs&#xff08;7.6) &#xff08;本文安装12.18.3&#xff09; mongodb&#xff08;2.6&#xff09;&#xff08;本文安装5.0.17&#xff09; 1.1 安装Nodejs 1.1.1 下载安装包 下载地址&#xff1a;https://nodejs.org/zh-cn/download/这里下载…

代码随想录训练营Day42|背包问题

目录 学习目标 学习内容 416. 分割等和子集 学习目标 01背包问题&#xff0c;你该了解这些&#xff01; 01背包问题&#xff0c;你该了解这些&#xff01; 滚动数组 416. 分割等和子集 学习内容 problems/背包理论基础01背包-1.md programmercarl/leetcode-master&#…

Java【网络编程2】详解ServerSocket和Socket类, 逐行代码解析如何服务器客户端通信(附代码)

文章目录 前言一、认识 Socket(套接字), TCP 协议和 UDP 协议1, 什么是 Socket(套接字)2, 浅谈 TCP 协议和 UDP 协议的区别和特点 二、基于 TCP 协议的 Socket API1, ServerSocket 类2, Socket 类 三、逐行代码解析网络编程1, 逐行解析客户端1.1, 核心成员方法 start() 2, 逐行…

【黑马笔记】Servlet简易教程

1. Servlet demo 0. 新建web app项目 记得去 web.xml 中删除多余的配置&#xff0c;以及新建对应的文件夹 1. 导入 Servlet依赖坐标 <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version&…

四块ACM区域赛金牌,我队友

是的&#xff0c;毕业12年以后&#xff0c;他来找我。     痛失网名了属于是&#xff0c;但是这不重要&#xff0c;​怎么说呢&#xff1f;有点激动&#xff0c;我得把这件事情记录下来&#xff0c;这是一位重量级的人物&#xff0c;也是大家眼中别人家的孩子。     他…