一、原理解释
git在版本库中保留了文件每一次更改,操作之后保留的版本号,我们可以根据对应版本号来将文件定向到对应的版本,比如我有一个文本文件tt.txt ,里面刚创建的时候有111三个数字,commit之后,我再添加222,再commit,我再添加333,然后再commit,然后再添加444,我再commit,这个时候我们查看我们的操作日志记录:
$git log --oneline 我们得到下面的四次操作,分别表示从
“创建”到
“三次插入”
c08a57a third insert
3826a87 second insert
78fc0a4 first insert
f82816c create successfully
3826a87 second insert
78fc0a4 first insert
f82816c create successfully
那我现在要回到“第一次插入”的那个状态怎么办呢?
$ git reset HEAD^^
执行这个操作之后再执行commit一次,即执行 git commit -a -m "restore" ,这个时候我们发现,当我们再次打开
$ git log --oneline 的时候,得到的结果为
0163ab5 restore
78fc0a4 first insert
f82816c create successfully
78fc0a4 first insert
f82816c create successfully
即相当于我们穿越了时空,回到了过去,因为在版本库里面,已经没有了second insert 和third insert的版本,那我们再怎么穿越回来呢?
正确的做法是根据每一次操作的版本号,再穿越回去就是了,什么意思呢,我先使用如下命令:
git reflog 得到下面的序列
0163ab5 HEAD@{0}: commit: restore
78fc0a4 HEAD@{1}: reset: moving to HEAD^^
c08a57a HEAD@{2}: commit: third insert
3826a87 HEAD@{3}: commit: second insert
78fc0a4 HEAD@{4}: commit: first insert
f82816c HEAD@{5}: commit (initial): create successfully
78fc0a4 HEAD@{1}: reset: moving to HEAD^^
c08a57a HEAD@{2}: commit: third insert
3826a87 HEAD@{3}: commit: second insert
78fc0a4 HEAD@{4}: commit: first insert
f82816c HEAD@{5}: commit (initial): create successfully
我们发现每一步操作,都可以通过reflog去查看相对应的版本号,因而我们只需要穿越回原来的版本号即可
$ git reset c08a57a //即穿越回第三次插入数据的那个地方
这时候我们再查看操作日志,
git log --oneline 得到和原来一样的日志
c08a57a third insert
3826a87 second insert
78fc0a4 first insert
f82816c create successfully
3826a87 second insert
78fc0a4 first insert
f82816c create successfully
这就说明又穿越回去了
二、总结
1、什么是HEAD
在执行版本的穿越之前,
首先,Git必须知道当前版本是哪个版本,在Git中,用
HEAD
表示当前版本,也就是最新的提交
3628164...882e1e0
(注意我的提交ID和你的肯定不一样),上一个版本就是
HEAD^
,上上一个版本就是
HEAD^^
,当然往上100个版本写100个
^
比较容易数不过来,所以写成
HEAD~100
。
HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令
git reset --hard commitID 。
-
穿梭前,用
git log
可以查看提交历史,以便确定要回退到哪个版本。 -
要重返未来,用
git reflog
查看命令历史,以便确定要回到未来的哪个版本。