git reset 和 git revert

一、四个工作区域

工作区(Work Space):是在电脑文件系统中能看到的项目目录,它包含项目的实际文件,你在工作区进行的修改会影响到这些文件。比如你新创建了一个文件夹,git init命令以后它就成为了一个git目录,然后你在文件夹里修改了一个 readme.txt 文件,也就是所谓的在工作区修改了它,这个很好理解。

暂存区(Index/Staging Area):是一个中间区域,用于暂存工作区中的改动,但这些改动还没有提交到本地仓库。在进行版本控制时,你需要明确地将修改添加到暂存区,这相当于一次“快照”,在提交到本地仓库之前,你可以对这次“快照”进行进一步的调整。这个区域比较抽象,我们暂时不需要看到它,只用记住在提交到本地仓之前,先添加到这儿就行。

本地仓库 (Local Repository):是存储在自己计算机本地的版本库,包含了完整的项目历史数据。执行git commit命令后会将暂存区的内容添加到这里,git会保存为一个新的提交,并更新本地仓库,这样就形成了项目的版本历史。这个区域也比较抽象,暂时不用担心。

远程仓库 (Remote Repository):是位于网络上的git仓库,通常托管在像 GitHub、GitLab 或 Bitbucket 等服务提供商上。远程仓库用于协作和备份。多个开发者可以共享同一个远程仓库,每个人可以将自己的改动推送到远程仓库,从而实现协同开发。同时,远程仓库也提供了项目的备份和存档。

二、背景知识

使用Git的每次提交,Git都会自动把它们串成一条时间线,这条时间线就是一个分支。如果没有新建分支,那么只有一条时间线,即只有一个分支,在Git里,这个分支叫主分支,即master分支。有一个HEAD指针指向当前分支(只有一个分支的情况下会指向master,而master是指向最新提交)。每个版本都会有自己的版本信息,如特有的版本号、版本名等。

如下图,假设只有一个分支:

三、问题描述

在利用Git进行多人合作程序开发的过程中,我们有时会出现错误提交的情况,此时我们希望能撤销提交操作,让程序回到提交前的样子,本文总结了两种解决方法:回退(reset)、反做(revert)。

四、git reset

git reset的作用是修改HEAD的位置,即将HEAD指向的位置改变为之前存在的某个版本。

4.1 实战使用

如下图所示,假设我们要回退到版本一:

reset前的版本展示

reset后,目标版本之后的版本不见了

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

第一步:使用下述命令查看版本号

git log

也可以通过git仓库的图形化界面查看版本号:

第二步:使用下述命令将版本回退

git reset --hard 目标版本号

再次使用git log命令查看版本信息,此时本地的HEAD已经指向之前的版本:

第三步:使用下述命令提交更改

git push -f

此时如果用 git push” 会报错,因为我们本地库HEAD指向的版本比远程库的要旧: 

所以我们要用 git push -f 强制推上去,就可以了:

此时查看远程库的HEAD也已经指向目标版本!!!

4.2 reset的四种模式

soft:适用于回退后不需要被回退的代码

  • 移动本地库HEAD指针
  • 重置暂存区
  • 重置工作区

mixed:适用于回退后要被回退的代码,被回退的代码在暂存区,当然也可以在工作区修改被回退的代码 

  • 移动本地库HEAD指针

hard:适用于回退后要被回退的代码,被回退的代码不在暂存区,当然也可以在工作区修改被回退的代码

  • 移动本地库HEAD指针

  • 重置暂存区

keep:适用于回退后要被回退的代码,被回退的代码在暂存区,因为要重置工作区,所以暂存区和工作区会存在冲突(要解决冲突) 

  • 移动本地库HEAD指针

  • 暂存区不变

  • 重置工作区

4.3 IDEA操作 

第一步:选择要回退到哪个版本(被选中的版本不会被回退)

第二步:选择回退的模式

也可以选择版本号进行回滚(注意:被选中的版本号不会被回滚)

五、git revert

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

5.1 实战使用

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

具体操作:

举个例子,现在库里面有三个文件:READ.md、text.txt、text2.txt。

第一步:查看版本号

可以通过命令行查看(输入git log)。如图,最近的两个版本分别叫:“add text.txt”(即新增了文件text.txt)、“add text2.txt”(新增了文件text2.txt)。这个时候我们不需要text.txt这个文件了,那就是说不想要“add text.txt”那个版本的操作,那可以通过反做“add text.txt”这个版本来实现。

也可以通过git仓库的图形化界面查看版本号:

第二步:使用“git revert -n 版本号”反做,并使用“git commit -m 版本名”提交

(1)反做,使用git revert -n 版本号命令。如下命令,我们反做版本号为8b89621的版本:

git revert -n 8b89621019c9adc6fc4d242cd41daeb13aeb9861

注意:这里可能会出现冲突,那么需要手动修改冲突的文件,而且要git add文件名。 

(2)提交,使用git commit -m 版本名,如: 

此时可以用“git log”查看本地的版本信息,可见多生成了一个新的版本,该版本反做了“add text.txt”版本,但是保留了“add text2.txt”版本:

第三步:使用git push命令腿上远程库版本信息

查看git仓库上显示的远程库版本信息:

此时查看仓库的文件,剩下两个:READ.md、text2.txt

5.2 IDEA操作

选择要revert的版本进行revert,如下图所示:

六、方案选择

1、上面讲这两种方案都讲了使用场景

2、说下选择revert时遇到的坑

比如某个需求开发完成后(A分支)需要合并到主分支,却不小心把B分支合到主分支,B分支还在开发中未能达到合并的要求,这种场景正常情况直接reset掉就行,假如选择了revert也可以达到目的,但是后面B开发完成需要合并主分支后,发现主分支合不上,原因是之前已经有个revert的记录,遇到这种情况只需要把之前的revert记录再revert一次就行(不推荐这种操作行为)。所以正确的选择回滚的方式可以避免不必要的麻烦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值