赞
踩
更好的阅读体验:点这里 ( www.doubibiji.com
)
我们进行了多次提交,发现之前的提交有问题,想回到更早之前的提交版本,该怎么处理呢?
下面讲解一下回到过去的方式。
git reset
命令可以让我们回到之前的提交状态。
git reset
命令有三种常用的模式:soft
、mixed
和 hard
。
下面来介绍这三种模式。
在介绍之前,先准备一下当前的状态。
首先我们进行了4次提交,并推送到了远程仓库,然后进行了第5次编辑,并暂存到了暂存区,然后进行了第6次编辑,第6次的编辑还在工作区。
还是以 1.txt 为例:
第一次提交后,内容为:
第一次添加
第二次提交后,内容为:
第一次添加、第二次添加
第三次提交后,内容为:
第一次添加、第二次添加、第三次添加
第四次提交后,内容为:
第一次添加、第二次添加、第三次添加、第四次添加
上面四次每次都推送到了远程仓库。然后再进行两次修改。
第五次修改后,进行了暂存,所以暂存区的内容为:
第一次添加、第二次添加、第三次添加、第四次添加、第五次添加
第六次修改后,没有暂存和提交,所以我们此时看到的内容,也就是工作区的内容为:
第一次添加、第二次添加、第三次添加、第四次添加、第五次添加、第六次添加
现在要回到第二次提交的状态。
通过历史记录,可以看到第二次提交的 ID 为 1db589fd79e748ac510207a9532aad244b031e73
。
此时远程仓库的提交记录为:
现在使用 hard 模式回到第二次提交
git reset --hard 1db589fd7
提交记录ID可以是前面的一部分,只要指定的部分不重复,能确定是当前的提交即可。
此时查看提交记录,如下:
可以看到本地的分支指向了第二次提交,因为这里有远程分支的缘故,所以还能看到第三次和第四次的记录。
此时我们查看本地 1.txt 的代码为:
第一次添加、第二次添加
可以看到,使用 hard 模式,暂存区和工作区中的内容会被全部删掉。
此时使用 git push
提交到远程是会报错的,以为本地的代码版本是比远程仓库的版本要旧的。
所以将结果推送到远程仓库,需要强制推送才行:
git push -f # -f 表示强制推送。
此时查看提交记录:
查看远程仓库的提交记录为:
可以看到本地和远程提交记录中,第二次提交后面的版本全部消失了。
结论:hard 模式,会清空暂存区和工作区所有的内容,并回退到指定节点,之后提交的节点内容全部删除。
回到初始状态,使用 soft 模式回退到第二次提交。
git reset --soft 1db589fd7
查看提交记录,因为显示了远程分支,才能看到第二次后面的提交记录:
此时我们查看本地 1.txt 的代码为:
第一次添加、第二次添加、第三次添加、第四次添加、第五次添加、第六次添加
此时回退到了第二次提交,可以看到,使用 soft 模式,第二次后面的提交、暂存区和工作区中的内容都没有丢失。
查看暂存区的内容:
可以看到第二次之后提交的内容没有被清理掉,都回到了暂存区。
结论:soft模式,不会清空暂存区和工作区的内容,第二次提交之后的节点内容都会回到暂存区,可以再次修改并提交,并强制push到远程仓库,并删除之前的提交记录。
回到初始状态,使用 mixed 模式回退到第二次提交。
# 默认就是 mixed 模式
git reset 1db589fd7
# 显式指定 mixed 模式
git reset --mixed 1db589fd7
此时我们查看本地 1.txt 的代码为:
第一次添加、第二次添加、第三次添加、第四次添加、第五次添加、第六次添加
此时回退到了第二次提交,可以看到,使用 mixed 模式,第二次后面的提交、暂存区和工作区中的内容都没有丢失。
但是查看暂存区的内容,发现暂存区内容取消了暂存:
也就是说,第二次之后提交的内容没有被清理掉,暂存区被清空了,但是所有的内容都没有丢失,而是都回到了工作区。
结论:mixed 模式,不会丢失暂存区和工作区的内容,第二次提交之后的节点的内容和暂存区的内容都会回到工作区,可以再次修改内容,并强制push到远程仓库,并删除之前的提交记录。
如果没有远程仓库,只在本地操作的话,在使用 git reset 以后,那么使用 git log 就看不到之后的提交记录了,如果不想回退了,就无法返回之后的提交了。
例如使用 git reset 到第二次提交,现在不想回退了,想重新回到第四次提交,使用 git log 查看,没有第四次的提交记录,无法获取第四次的 commit id。
那么可以使用下面的指令获取到历史的变动信息,找到第四次的提交ID。
git log -g
# 或者使用
git reflog show
在上面回退的时候,回退到某次提交,是将该次之后所有的提交都回退了。
而 git revert
可以只撤回某一次的提交。
例如,我只撤回第二次的提交,第三次和第四次的提交不撤回。
但是这样做,可能会引起冲突,比如在第二次提交的时候,添加了一些内容,在后面的第三次第四次提交的时候,对这些内容进行了修改,此时撤销第二次的提交,不能简单的将第二次的提交内容删除,所以肯定会存在冲突。
演示一下
假设我们有四次提交记录:
每次添加一段内容,最后 1.txt 内容如下:
第一次添加、第二次添加、第三次添加、第四次添加
现在使用 git revert 撤销第二次的提交:
git revert 1db589fd79e
查看一下 revert 后的 1.txt 的内容,发现出现了冲突:
这个时候,我们就可以合并冲突,然后提交了。
提交后,查看提交记录,可以看到和 git reset
不同,git reset
回退后,之前的提交记录也删除了。但是 git revert
回退后,之前的提交记录还是存在的,也就是第二次提交的记录还是存在的,只是当前把第二次提交的内容删除,形成一次新的提交。
如果我们现在的工作树是下面这样的:
如果现在有一个特殊的版本,它的功能和主线功能不一样,我现在要在 C2 提交的基础上来开发这个新的版本。
那么我们可以切换到 C2 的提交:
git switch 1db589fd79e --detach # 第二次提交的ID
因为现在正在进行一个比较危险的操作,就是分离头指针,也就是头指针没有指向某个分支的头部。所以必须添加 --detach
参数。
执行完上面的指令,工作树会变成下面这样,HEAD 和 Master 分离了。
此时 HEAD 指向了 C2,所以看到 1.txt 就是 C2 时提交的代码,但是此时是不能修改代码的,因为如果修改了代码,新增的节点是放在哪里呢?放在 C4 后面还是 C6 后面。
现在我们从 C2 的地方创建一个 test 分支:
git switch -c test 1db589fd79e
可以在 test 分支上进行修改,修改完成,提交到新的分支。
此时的工作树是这样的,就不是分离头指针了,工作树会变成如下:
这样就没有问题了。
如果要切换重新回到 master 分支的头,可以使用如下指令:
git switch master
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。