Git 中的回退操作:reset 和 revert
Git 中回退有 reset 和 revert,这两个的区别就是是否保留更改记录
假设当前的提交情况是:A <- B <- C <- D <- HEAD,如下图:

当前是 D,希望回退到 A,那我们可以使用 reset 命令,reset 后再看 git log 就会发现:B <- C <- D 宛如没有出现过,这适用于想完全舍弃 A 之后的修改
但是如果我们想保留 B <- C <- D 的修改记录,可能这三个 commit 的功能只是暂时用不到,以后可能还用到,或者可能当前分支是一个公共分支,B <- C <- D 可能已经被同步到了其他小伙伴电脑上,为了尽量避免代码冲突。这些情况就需要使用 revert 命令,这样会重新生成新的 commit,其中包含回退的记录(假设 D 这个 commit 是添加了一些代码,那么 revert D 的 commit 就是删除这些代码)
reset
使用 git reset A ,reset 会修改 head 的指向,这样可以回滚到 A,默认使用的参数是 --mixed,这个参数决定了 reset 时 Git 该如何处理工作区和暂存区
一般地,我们对于代码的修改会体现在 working tree(工作区)的变动,通过 git add 添加即将要提交的文件到 index(暂存区),通过 git commit 再提交到 repository(本地仓库),如下图:

查看帮助:git help reset
git reset [<mode>] [<commit>]
This form resets the current branch head to <commit> and possibly updates the index (resetting it to the
tree of <commit>) and the working tree depending on <mode>. If <mode> is omitted, defaults to --mixed. The
<mode> must be one of the following:
--soft
Does not touch the index file or the working tree at all
--mixed
Resets the index but not the working tree
--hard
Resets the index and working tree
假设我们现在处在 D,那么分别会有三种 reset 的情况
- 我们执行
git reset --soft A,字面意思,轻柔地 reset,只将repository回滚到了A,而working tree、index维持reset之前的状态,保持不变,这个时候直接执行commit,这时候会得到一个和D修改内容相同的 commitD'(二者的 commit id 是不相同的),--soft很适合呈现多次 commit 的修改的叠加效果,假设B、C、D都是针对某一个功能的修改,其中的 commit 可能修改了同一个文件,想整合这些 commit 都修改了哪些内容,就可以使用--soft从Dreset 到A,那么B、C、D的修改都会出现在index中

- 我们执行
git reset --mixed A,repository、index会回滚,working tree维持reset之前的状态,这个时候直接 commit,将无法提交,因为repository与index都被回滚了,二者是相同的,没有变化则无法提交 commit

- 我们执行
git reset --hard A,按照参数hard的字面意思,reset 的非常强硬,repository、index、working tree都会回滚到A,因为working tree工作区也回滚了,所以本地的所有修改也将丢失,--hard相对来说比较危险,需要确保工作区没有需要保留的代码,--hard适合的情况是对于当前的即将要提交的代码失去信心,准备推倒重来

revert
如果想在回滚的同时保留 commit 记录,就需要使用 revert,revert 就是生成原 commit 逆向修改的 commit,从而实现会滚。当前是 D,希望回退到 A,就需要按顺序依次 revert D、C、B :
git revert D
git revert C
git revert B

每一次 revert 都会生成新的 commit,需要依次手动输入 commit message,也可以先 revert 最后集中 commit
git revert --no-commit D
git revert --no-commit C
git revert --no-commit B
git commit -m " Revert D C B"
使用 revert 需要注意,如果即将 revert 的 commit 是一个 merge commit,那么会出现错误
使用 reset 方式,创建回滚的 commit
如果需要保留回滚记录,但是需要 revert 的 commit 是 merge commit,那就必须手动指定 mainline,比较麻烦,可以用 reset 的方式创建回滚 commit,这种方式不受 merge 方式的影响:
git reset --hard A
git reset --soft D
git commit -m " Revert D C B"
通过这种方式也能回滚回 A,并且生成一个新的 commit,其中包括了 D、C、B 的逆向修改:
先
reset --hard到A,这时repository、index、working tree都会回滚到A

再
reset --soft到D,这时repository指向了D,但是index和working tree还保持在A,当前即将 commit 的就是B、C、D逆向修改的叠加

参考资料
git reset soft,hard,mixed之区别深解
What's the difference between git reset --mixed, --soft, and --hard?
How can I revert multiple Git commits?
相关阅读:Git 常见操作梳理
Git 中的回退操作:reset 和 revert的更多相关文章
- 大话git中的撤销操作
下面以现实场景作为情境. 基础知识,理解git中的几个区域 本地代码已经add,未commit 修改本地工作目录中的readme.md,添加文字"第一次修改" 然后查看下状态 ➜ ...
- 『现学现忘』Git基础 — 23、Git中的撤销操作
目录 1.撤销操作说明 2.撤销工作区中文件的修改 3.撤销暂存区中文件的修改 4.总结 1.撤销操作说明 我们在使用Git版本管理时,往往需要撤销某些操作.比如说我们想将某个修改后的文件撤销到上一个 ...
- git中的文件操作
现在我们的机器上有了一个 真实项目 的 Git 仓库,并从这个仓库中检出了所有文件的 工作副本. 通常,你会对这些文件做些修改,每当完成了一个阶段的目标,想要将记录下它时,就将它提交到仓库. git中 ...
- git中通过实际操作来了解常用命令
基本的6个命令 常用的就下面6个命令,但是详细的可能有上百个命令. 还需要特别了解git的几个名词,workspace:工作区,Index/Stage:暂存区,Respository:本地仓库,Rem ...
- Git 中的一些其他常用命令
1.查看提交的历史版本(git log) 我们可以使用 git log 命令来查看提交的历史版本. 默认不用任何参数的话,git log 会按提交时间列出所有的更新,最近的更新排在最上面.每个版本都有 ...
- Git命令之回退篇 git revert git reset
Git command之回退篇 欲练回退 必先了解:HEAD.index.WorkingCopy HEAD: 当前所在的分支版本顶端的别名,也就是最新的一次commit. git commit 之后与 ...
- git中reset与revert的使用
http://alpha-blog.wanglianghome.org/2010/07/30/git-partial-rollback/ reset(版本撤回) 格式 git reset [-q] [ ...
- Git回退---reset和revert
今天学习了git回退的两个命令,现在总结一下: 1.git reset 如果想回退错误的提交C和D,只要把指针移到B上 git reset --hard a0fvf8 而这时候,远程仓库的指针还在D上 ...
- git reset 版本回退操作
1 git回退命令 git reset --hard GIT_HEAD GIT_HEAD是你具体要回退的分支: 如图: 注: 查询GIT_HEAD可以通过两个命令:git log 获取未删除 ...
随机推荐
- 视网膜血管分割代码(Pytorch实现)
创建日期: 2021-12-24 17:00:00 update log(2021.12.24):B站视频删除了,回放看了一下,讲的不太行......2333,时间过得真快,转眼就是2022年了啊 2 ...
- 数据库界的Swagger:一键生成数据库文档!
对于开发的API文档,我们可以通过Swagger等工具来自动生成了.但是对于数据库表结构的文档呢,在实际开发中在开发前我们一般会先设计好表结构,大家讨论一下, 这个时候就很需要有个数据库表结构的文档, ...
- python appium server代码启动和关闭遇到的坑
第一次使用博客,小白级,互相交流,有说的不对的地方欢迎来喷!!! 自动化的目的就是减少人工成本,如果每次跑自动化用例时都要手动起appium客户端,太费事了~~故,将appium server的调起和 ...
- Barbican密钥管理器服务
Barbican服务介绍 Key Manager 服务 (barbican) 提供机密数据的安全存储.配置和管理.这包括密钥材料,例如对称密钥.非对称密钥.证书和原始二进制数据. Barbican 是 ...
- Apache Struts 2 漏洞汇总
Apache Struts2 是一个基于MVC设计模式的Web应用框架,会对某些标签属性(比如 id)的属性值进行二次表达式解析,因此在某些场景下将可能导致远程代码执行. Struts2特征: 通过页 ...
- SHCTF web题
第一题:直接查看robots.txt,得到flag 第二题:他的题的意思通过get方式一个字符一个字符去猜如果对的话他下面的小方格就会亮起,用python写个脚本就过了 第三题:也是猜flag 解题方 ...
- 论文解读(SAGPool)《Self-Attention Graph Pooling》
论文信息 论文标题:Self-Attention Graph Pooling论文作者:Junhyun Lee, Inyeop Lee, Jaewoo Kang论文来源:2019, ICML论文地址:d ...
- psexec.py规避杀软
前言 在内网渗透中,当获取到一个账号密码后,经常会使用impacket套件中的psexec.py进行远程连接并执行命令,但是因为用的人多了,杀软也对psexec.py特征进行了拦截,也就导致了如果使用 ...
- 个人NuGet服务搭建,BaGet保姆及部署教程
前言 应该或许大概每个公司都会有自己的NuGet包仓库吧. 不会吧!不会吧!不会吧!不会还没有自己的仓NuGet仓库吧! 开个玩笑,虽然我觉得有没有无所谓,但是为了这篇博客它必须有所谓. 在工具的选择 ...
- 『忘了再学』Shell基础 — 22、主要的环境变量配置文件说明
目录 1.source命令 2.Linux系统中环境变量配置文件 (1)登录时生效的环境变量配置文件 (2)/etc/profile环境变量配置文件 (3)/etc/profile.d/*.sh环境变 ...