版本回退
上篇咱们说过,GIT能够管理文件的历史版本,这也是版本控制器重要的能力。如果有一天你发现之前做的工作出现很大问题,需要在某个特定的历史版本重新开始,这个时候,就需要版本回退的功能了。
执行git reset
命令用于回退版本,可以指定退回到某一次提交的版本。”回退“本质是将版本库中的内容进行回退,工作区和暂存区是否回退有命令参数决定。git reset
命令的语法格式:git reset [--soft | --mixed | --hard] [HEAD]
--mixed
为默认选项,使用时可以不用带该参数。该参数将暂存区的内容回退到指定提交版本内容,工作区文件保证不变。--soft
参数对于工作区和暂存区的内容都不变,只是将版本库回退到某个指定版本--hard
参数将暂存区与工作区都回退到指定版本,切记工作区有未提交的代码时不要使用该参数,因为工作区会回滚,你没有提交的代码就再也找不回了。HEAD
说明:- 可以直接写成commit id,表示回退到指定版本
- HEAD 表示当前版本
- HEAD^ 表示上一个版本
- HEAD^^ 表示上上一个版本,以此类推
- HEAD~0 表示当前版本
- HEAD~1 表示上一个版本
- HEAD^2 表示上上一个版本,以此类推
为了演示版本回退,咱们先更新三个版本,并分别进行3次提交。
咱们使用git log --pretty=oneline
来查看一下历史提交记录
如果在提交完version3后,发现version3编写错误,想回退到version2,重新基于version2开始编写。
由于我们希望将工作区的内容也回退到version2版本,所以需要使用
--hard
参数
此时我们使用git log
查看一下提交日志,发现HEAD
指向version2
值得一提的是,GIT的版本回退速度非常快,因为GIT在内部有一个指向当前分支(此处是master分支)的HEAD指针,refs/heads/master
文件中保存当前master
分支的最新commit id
。当我们在回退版本的时候,Git仅仅是给refs/heads/master
中存储一个特定的version,示意图如下
如果此时先要从version2回到version3要怎么做呢?
只需要知道version3的commit id
但此时使用git log
命令无法打印出version 3的commit id
,运气好的话还可以在终端上查找到之前的记录,运气不好的话commit id
已经被丢弃了。好在Git为我们提供了git reflog
命令,该命令用来记录本地的每一次命令
我们发现打印出来的commit id
比以前短了,但是没关系,GIT版本回退的时候,也可以使用部分commit id
来代表目标版本
撤销修改
如果我们在工作区写了很长时间的代码,越写越写不下去,觉得写的代码太垃圾,想恢复到上一个版本。
情况1:工作区的代码还未add
你当然可以直接删除掉你目前在工作区新增的代码,但是当你写了很多代码,就没有办法分辨出哪些代码是新增的。当然你可以使用git diff
查看差别在哪,但是这样效率太低了,而且容易改错了。
Git为我们提供了更好的方式,使用git checkout --[file]
命令让工作区的文件回退到最近一次add
或commit
时的状态。
情况2:已经add,但没有commit
我们可以使用git reset
回退命令,参数设置为--mixed
(可以不写),将暂存区的内容回退到指定的版本内容,工作区保持不变。
情况3:已经add,并且也commit
我们可以使用git reset --hard HEAD^
回退到上一个版本!前提条件是你还没把代码推送到远程仓库中。
删除文件
在Git中删除也是一个修改操作,将已经提交过的file2文件删除要怎么处理呢?
我们直接使用rm -rf
删除file2文件是没有用的,通过git status
会告诉你哪些文件被删除了。此时,工作区和版本库不一致,要删除文件,不但要删除工作区的文件,还要删除版本库的文件。
走到这里有两种情况
- 不小心删错了
- 确实要从版本库中删除该文件
对于第一种情况,可以使用git checkout -- file2
回退到删除前。
对于第二种情况,很明显我们没有删除干净,我们只删除了工作区的文件,需要使用git rm
将文件从暂存区和工作区中删除,并且commit