Git系列(四)——版本回退
我们已经学会了创建和修改文件,那也就是说我们已经生成了很多个版本,这样我们也就可以来学习版本的回退了。
工作区和暂存区
首先,我们来了解工作区和暂存区这两个概念:
- 工作区就是我们能看到的目录,比如
learngit
这个目录,就是我们的工作区; - 暂存区就是我们通过
git add
这个指令,将修改提交到的地方,图中的stage
; - 除此之外,
git commit
是把这些修改提交到我们自动创建的第一个分支master
,还有一个指向master
的指针HEAD
(这两个概念我们之后再讲)
这样我们就可以理解为什么Git上传或者修改文件都需要两步,而且每次commit
都是将暂存区的所有修改一起提交到分支,所以说,如果我们有很多个修改,一定要用git add
指令全部添加到暂存区之后,再一起上传到分支。
我们来举一个例子:我们再在learngit
目录下创建一个文件README.txt,内容如下:
1 | I am learning git |
并且把我们之前的tmp.txt
文件再加一行变成:
1 | I like Git |
然后,我们使用git status
来看看我们的修改:
1 | $ git status |
很明显,git定位到了我们的修改,我们可以看到README.txt
的状态是Untracked files
,这是因为我们还没有将这个文件上传,现在,我们使用git add
对两个文件进行添加后,我们再用git status
来看一下:
1 | $ git status |
在这个时候,这两个修改都在暂存区里,git就会提示我们使用git commit
来进行上传,然后我们就用git commit
将修改进行上传,这时候我们再使用git status
查看一下:
1 | $ git statua |
这时候,Git就告诉我们,整个世界都是干净的了!
我们可以两次add
后再进行commit
,但是我们不能add
–commit
–add
,后者的第二次add
的内容就不会被上传到分支。总之,我们在操作git时,最后一步一定是commit
。
版本回退
版本回退这个功能就意味着,我们可以有无限的犯错机会,就像我们打单机游戏最后的boss之前,我们都会先存档,这样我们就算失败了也可以无限次的从头再来,git的版本回退功能也是一样的道理。
我们的工作目录learngit
已经经历了很多次修改,也产生了很多个版本,我们想要进行版本回退,我们首先需要知道都有那些版本,我们可以用git log
这个指令
1 | $ git log |
我们可以清晰的看到有三次提交,如果觉得信息太多看的眼花缭乱的话,我们可以加上--pretty=oneline
参数:
1 | $ git log --pretty=oneline |
前面的这一大串数字是commit id
(版本号),是每个版本的唯一标识。
现在我们就坐上时光穿梭机把tmp.txt
回退到上一个版本吧,首先我们需要知道,HEAD
表示当前版本,也就是最新的5b8c051...
,上一个版本就是HEAD^
,上上个版本就是HEAD^^
,100个版本之前就是HEAD~100
。
我们如果想回退到上一个版本,我们就需要使用git reset
命令:
1 | $ git reset --hard HEAD^ |
--hard
参数的含义我们之后再讲,这里直接用就可以了,我们来看一下tmp.txt
的内容:
1 | $ cat tmp.txt |
果然,被还原了,而且最新添加的README.txt
文件也消失了。
现在我们来看一下我们现有的版本信息:
1 | $ git log |
Oh my God!最后的那个版本消失了,我们真的穿越了,那可以传回去嘛?答案是肯定的,我们只需要向上翻一番记录找到最新版本的commit id
,然后使用如下指令:
1 | $ git reset --hard 5b8c0 |
这样就变回去了,最后那个commit id
不用写全,写前几位就可以,Git会自动为你寻找的。
我们来看一下tmp.txt
的内容:
1 | $ cat tmp.txt |
嗯,没错,它又回来了。
这时候,可能就会有朋友问,如果我忘记了commit id
怎么办呢?放心,Git很强大的,他会提前想到所有的情况的,git reflog
这个命令用来记录你的每一次命令,如下:
1 | $ git reflog |
Oh Nice! 我又可以知道我的commit id
了,然后我们就可以随心所欲地版本回退了。
本次教程就到此结束了,本次知识点较多,大家要多复习呦。