git教程学习来自廖雪峰的官方网站
1.版本回退
修改readme.txt文件提交到Git版本库,例如:
Git is a distributed version control system.
Git is free software
任意修改几个版本进行add和commit以后,考虑一下当前的版本已经更迭到几代了?
在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log
命令查看
$ git log commit e82e6f6c8b90fbf95f23273e7c7a37973529d463 (HEAD -> master) Author: leox <leox520@163.com> Date: Wed Sep 4 15:21:19 2019 +0800 append HAHAHA commit cf418a19d4725b02680b08b83414cea9bb0c797b Author: leox <leox520@163.com> Date: Wed Sep 4 15:18:46 2019 +0800 append GPL commit 7f6805e527555bc4a2d153a6e85ec86a2661f2f2 Author: leox <leox520@163.com> Date: Wed Sep 4 14:52:31 2019 +0800 添加了一个txt文件
git log
命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append HAHAHA
,上一次是add GPL
,最早的一次是 添加了一个txt文件。
如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline
参数:
$ git log --pretty=oneline e82e6f6c8b90fbf95f23273e7c7a37973529d463 (HEAD -> master) append HAHAHA cf418a19d4725b02680b08b83414cea9bb0c797b append GPL 7f6805e527555bc4a2d153a6e85ec86a2661f2f2 添加了一个txt文件
需要友情提示的是,你看到的一大串类似e82e6f6c8b...
的是commit id
(版本号),和SVN不一样,Git的commit id
不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id
和我的肯定不一样,以你自己的为准。为什么commit id
需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
好了,现在我们启动时光穿梭机,准备把readme.txt
回退到上一个版本,也就是add GPL
的那个版本,怎么做呢?
首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD
表示当前版本,也就是最新的提交e82e6f6c8b...
(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^
,上上一个版本就是HEAD^^
,当然往上100个版本写100个^
比较容易数不过来,所以写成HEAD~100
。
现在,我们要把当前版本append HAHAHA
回退到上一个版本add GPL
,就可以使用git reset
命令:
$ git reset --hard HEAD^ HEAD is now at cf418a1 append GPL
然后现在去查看readme.txt文件,果然被还原了。
还可以继续回退到上一个版本wrote a readme file
,不过且慢,然我们用git log
再看看现在版本库的状态:
$ git log commit cf418a19d4725b02680b08b83414cea9bb0c797b (HEAD -> master) Author: leox <leox520@163.com> Date: Wed Sep 4 15:18:46 2019 +0800 append GPL commit 7f6805e527555bc4a2d153a6e85ec86a2661f2f2 Author: leox <leox520@163.com> Date: Wed Sep 4 14:52:31 2019 +0800 添加了一个txt文件
最新的那个版本append GPL
已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?
办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append HAHAHA
的commit id
是e82e6f6c8b9...
,于是就可以指定回到未来的某个版本:
$ git reset --hard e82e6 HEAD is now at e82e6f6 append HAHAHA
然后再查看readme.txt文件,HAHAHA又回来了!!
$ cat readme.txt
Git is a distributed version control system. sound HAHAHA.
Git is free software distributed under the GPL.
Git的版本回退速度非常快,因为Git在内部有个指向当前版本的HEAD
指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL
:
┌────┐
│ HEAD │
└────┘
│
└──> ○ append GPL
│
○ add distributed
│
○ wrote a readme file
改为指向add distributed
:
┌────┐
│ HEAD │
└────┘
│
│ ○ append GPL
│ │
└──> ○ add distributed
│
○ wrote a readme file
然后顺便把工作区的文件更新了。所以你让HEAD
指向哪个版本号,你就把当前版本定位在哪。
现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的commit id
怎么办?
在Git中,总是有后悔药可以吃的。当你用$ git reset --hard HEAD^
回退到add HAHAHA
版本时,再想恢复到append GPL
,就必须找到append GPL
的commit id。Git提供了一个命令git reflog
用来记录你的每一次命令:
$ git reflog e82e6f6 (HEAD -> master) HEAD@{0}: reset: moving to e82e6 cf418a1 HEAD@{1}: reset: moving to HEAD^ e82e6f6 (HEAD -> master) HEAD@{2}: commit: append HAHAHA cf418a1 HEAD@{3}: commit: append GPL 7f6805e HEAD@{4}: commit (initial): 添加了一个txt文件
终于舒了口气,从输出可知,append GPL
的commit id是cf418a1,现在,你又可以乘坐时光机回到未来了。