版本回退

  1. HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令 git reset --hard <COMMIT ID>
  2. 穿梭前,用 git log 可以查看提交历史,以便确定要回退到哪个版本。
  3. 要重返未来,用 git reflog 查看命令历史,以便确定要回到未来的哪个版本。

git log

假设我们有一个 readme.txt 文件, 一共有三个版本被提交到 Git 仓库里了, 用 git log -n 命令查看提交记录.

其中 n 代表显示最近提交的几次更改:

$ git log -3
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Tue Aug 20 15:11:49 2013 +0800
    append GPL
commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Tue Aug 20 14:53:12 2013 +0800
    add distributed
commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <askxuefeng@gmail.com>
Date:   Mon Aug 19 17:51:55 2013 +0800
    wrote a readme file

如果嫌输出信息太多,看得眼花缭乱的,可以加上 --pretty=oneline 参数:

$ git log --pretty=oneline
3628164fb26d48395383f8f31179f24e0882e1e0 append GPL
ea34578d5496d7dd233c827ed32a8cd576c5ee85 add distributed
cb926e7ea50ad11b8f9e909c05226233bf755030 wrote a readme file

可以看到的一大串类似 3628164...882e1e0 的是 commit id(版本号),和SVN不一样,Git 的 commit id 不是 1,2,3…… 递增的数字,而是一个 SHA1 计算出来的一个非常大的数字,用十六进制表示,而且你看到的 commit id 和我的肯定不一样,以你自己的为准。为什么 commit id 需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用 1,2,3…… 作为版本号,那肯定就冲突了。

git reset --hard

现在如果想把 readme.txt 回退到上一个版本,也就是 'add distributed' 的那个版本,怎么做呢?

首先,Git 必须知道当前版本是哪个版本,在 Git 中,用 HEAD 表示当前版本,也就是最新的提交 3628164...882e1e0,上一个版本就是 HEAD^,上上一个版本就是 HEAD^^,当然往上 100 个版本写 100个^ 比较容易数不过来,所以写成 HEAD~100

现在,我们要把当前版本 'append GPL' 回退到上一个版本 'add distributed',就可以使用 git reset 命令:

$ git reset --hard HEAD^
HEAD is now at ea34578 add distributed

也可以通过 commit id 指定回到过去或未来的某个版本:

$ git reset --hard 3628164
HEAD is now at 3628164 append GPL

版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。

Git 的版本回退速度非常快,因为 Git 在内部有个指向当前版本的 HEAD 指针,当你回退版本的时候,Git仅仅是把HEAD从指向append GPL:

改为指向add distributed:

然后顺便把工作区的文件更新了。所以你让HEAD指向哪个版本号,你就把当前版本定位在哪。

git reflog

现在,你回退到了某个版本,关掉了电脑,第二天早上就后悔了,想恢复到新版本怎么办?找不到新版本的 commit id 怎么办?

在 Git 中,总是有后悔药可以吃的。当你用 git reset --hard HEAD^ 回退到 add distributed 版本时,再想恢复到 append GPL ,就必须找到 append GPL 的 commit id。Git 提供了一个命令 git reflog 用来记录你的每一次命令:

$ git reflog
ea34578 HEAD@{0}: reset: moving to HEAD^
3628164 HEAD@{1}: commit: append GPL
ea34578 HEAD@{2}: commit: add distributed
cb926e7 HEAD@{3}: commit (initial): wrote a readme file

终于舒了口气,第二行显示 append GPL 的 commit id 是 3628164,现在,你又可以乘坐时光机回到未来了。

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress