Git回滚操作,工作区和暂存区恢复修改删除的文件

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

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

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

工作区和暂存区回滚

git restore

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

撤销工作区文件更改

我们在工作区修改了某个文件,然后我们想放弃此次修改,那么可以使用git restore 文件路径。修改文件后,我们查看文件状态,可以看到文件状态已经变化。

git status -s

输出:
 M README.md


// 回滚所有变动的文件
git restore *


// 回滚某个文件
git restore README.md

如果我们同时修改了多个文件,想全部撤销,则可以执行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命令的局限性:

它无法直接对暂存区的文件撤销到原始未修改状态。
也没有能力直接将工作区与暂存区文件同时撤销到原始未修改状态。
接下来我们可以看看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 --soft 回 HEAD~(HEAD 的父结点)时,其实就是把该分支移回原来的位置,而不会改变暂存区和工作区。

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

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

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

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

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

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

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

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

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

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

移动 HEAD 指向的分支 (若指定了 --soft,则到此停止)
重置 index 以便和 HEAD 相匹配 (若未指定,或指定 --mixed,则到此停止)
使工作区看起来像暂存区 (若指定 --hard)
reset与revert的区别
git reset 是回滚到对应的commit-id,相当于是删除了commit-id以后的所有的提交,并且不会产生新的commit-id记录,如果要推送到远程服务器的话,需要强制推送-f
git revert 是反做撤销其中的commit-id,然后重新生成一个commit-id。本身不会对其他的提交commit-id产生影响,如果要推送到远程服务器的话,就是普通的操作git push就好了。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

普发Pfeiffer CCR263 CCR272 CMR261 CMR273 PBR260 IMR265 TPR265 使用说明手侧

普发Pfeiffer CCR263 CCR272 CMR261 CMR273 PBR260 IMR265 TPR265 使用说明手侧

4G/5G布控球/移动执法仪在电力巡检远程视频智能监控方案中的应用

一、背景与需求 随着科技的不断进步&#xff0c;视频监控技术已成为电力行业不可或缺的一环。电力行业的巡检及建设工作&#xff0c;因施工现场在人迹罕见的野外或山区&#xff0c;地形复杂多变&#xff0c;安全更是重中之重&#xff0c;现场工作的视频图像需实时传回监管中心…

用html写一个加载页面动画

<!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><title>加载页面动画Ⅴ</title><link rel"stylesheet" href"./style.css"> </head><body><div class"al…

【Git】安装 Git

文章目录 1. CentOS 下安装2. Ubuntu 下安装 Git 是开放源代码的代码托管工具&#xff0c;最早是在 Linux 下开发的。开始也只能应用于 Linux 平台&#xff0c;后面慢慢的被移植到 Windows 下。现在&#xff0c;Git 可以在 Linux、Unix、Mac 和 Windows 这几大平台上正常运行了…

【每日力扣】15. 三数之和与11. 盛最多水的容器

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 15. 三数之和 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k…

【Proteus】蜂鸣器播放音乐

按键按一次&#xff0c;蜂鸣器响一次 &#xff0c;LCD1602同步。 #include <REGX52.H> #include <INTRINS.H>unsigned int keynum; sbit RSP3^0; //** sbit RWP3^1; //** sbit EP3^2; //** sbit buzzerP1^5; void delay(unsigned int n)//1ms {unsigned char a,…

树莓派安装tensorflow

树莓派安装tensorflow 使用编译好的版本自己选择版本进行编译armv71 架构 教程转载 使用编译好的版本 下载tensorflow编译好的版本 https://github.com/lhelontra/tensorflow-on-arm/tags由于python版本支持有限可能需要自己安装python 安装对应的python 自己选择版本进行编译…

【Golang】并发编程之三大问题:原子性、有序性、可见性

目录 一、前言二、概念理解2.1 有序性2.2 原子性后果1&#xff1a;其它线程会读到中间态结果&#xff1a;后果2&#xff1a;修改结果被覆盖 2.3 可见性1&#xff09;store buffer(FIFO)引起的类似store-load乱序现象2&#xff09;store buffer(非FIFO)引起的类似store-store乱序…

Java web应用性能分析概叙

“系统慢”&#xff0c;这是任何一个应用都会出现的问题&#xff0c;面对“系统慢”的问题&#xff0c;客户、测试、开发、管理者等不同角色的人员有不同反应&#xff1a; 客户&#xff1a;啥破东西啊&#xff0c;这么卡&#xff01; 测试&#xff1a;性能bug已提交。 开发&…

嵌入式工程师如何摸鱼?

有老铁问我&#xff0c;做嵌入式开发要加班吗&#xff1f; 也不知道搞什么鬼&#xff0c;现在的年轻人对加班这么抵触。 我刚做开发那会&#xff0c;啥也不懂&#xff0c;每天基本都要加班到晚上7-9点不等&#xff0c;我并不抵触加班&#xff0c;因为早早回家&#xff0c;也没什…

常见的地图绘制方法,这个包全包了~~

在上一篇介绍完Bokeh精美可视化作品之后&#xff0c;有小伙伴咨询我能不能稍系统的介绍下如何在地图上添加如柱形图等其他元素的付方法&#xff1f; 这就让我想到一个优秀的地图绘制可视化包-R-cartography&#xff0c;虽然之前也有简单介绍过&#xff0c;本期就具体分享下该包…

Axure实现导航栏的展开与收缩

Axure实现导航栏的展开与收缩 一、概要介绍二、设计思路三、Axure制作导航栏四、技术细节五、小结 一、概要介绍 使用场景一般是B端后台系统需要以导航栏的展开与收缩实现原型的动态交互&#xff0c;主要使用区域是左边或者顶部的导航栏展开与收缩&#xff0c;同一级导航下的小…

【六】fastapi+vue前后端分离项目

前端代码 https://gitee.com/feiminjie/helloworldfront 后端代码 https://gitee.com/feiminjie/helloworld 整体效果 首页 用例管理页 用例详情页

在vue中发现一个prop新的写法在官方文档没有,查百度不行,还有什么其他方法排查不

先看图&#xff0c;最近在接手一个同事的代码&#xff0c;发现prop有这样的写法&#xff1a; 我自己查了官网&#xff0c;以及百度都没有找到这种写法。这时我灵机一动&#xff0c;想到一个方法&#xff0c;vscode有内置的typesscript&#xff0c;自然有prop类型推断&#xff0…

我用这10招,能减少了80%的BUG

前言 对于大部分程序员来说&#xff0c;主要的工作时间是在开发和修复BUG。 有可能修改了一个BUG&#xff0c;会导致几个新BUG的产生&#xff0c;不断循环。 那么&#xff0c;有没有办法能够减少BUG&#xff0c;保证代码质量&#xff0c;提升工作效率&#xff1f; 答案是肯…

:has()伪类使用

下面的 CSS 代码表示如果 <a> 元素里面有 <img> 元素&#xff0c;则这个 <a> 元素就会匹配。 a:has(img) { display: block; } 我们可以使用这个选择器轻松区分是文字链接还是图像链接 a:has(> img) { display: block; } 表示匹配子元素是 <img>…

NineData正式将SQL开发正式升级为数据库DevOps

NineData SQL 开发早期主要提供 SQL 窗口&#xff08;IDE&#xff09;功能&#xff0c;产品经过将近两年时间的打磨&#xff0c;新增了大量的企业级功能&#xff0c;时至今日已经服务了上万开发者&#xff0c;覆盖了数据库设计、开发、测试、变更等生命周期的功能。 为了让企业…

面试:sleep 和 wait

一、共同点 wait(),wait(long)和sleep(long)的效果都是让当前线程暂时放弃CPU的使用权&#xff0c;进入阻塞状态 二、不同点 1、方法归属不同 sleep(long)是Thread的静态方法而wait(), wait(long)都是Object的成员方法&#xff0c;每个对象都有 2、醒来的时机不同 执行sleep(l…

2024第十五届蓝桥杯JavaB组省赛部分题目

目录 第三题 第四题 第五题 第六题 第七题 第八题 转载请声明出处&#xff0c;谢谢&#xff01; 填空题暂时可以移步另一篇文章&#xff1a;2024第十五届蓝桥杯 Java B组 填空题-CSDN博客 第三题 第四题 第五题 第六题 第七题 第八题 制作不易&#xff0c;还请点个赞支持…

钉钉OA审批评论接口,如何@ 人并发送通知

钉钉OA审批评论接口&#xff0c;如何 人并发送通 问题描述&#xff1a; 相关接口&#xff1a;https://oapi.dingtalk.com/topapi/process/instance/comment/add 我希望在钉钉oa审批流程中&#xff0c;添加评论的同时通过“”或者其他方式提醒流程发起人去跟进审批工作。 但我…