现在,你已经学会了修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改readme.txt文件如下:

Git is a distributed version control system.
Git is free software distributed under the GPL.

然后尝试提交:

$ git add readme.txt
$ git commit -m "append GPL"
[master ] append GPL
file changed, insertion(+), deletion(-)

像这样,你不断对文件进行修改,然后不断提交修改到版本库里,就好比玩RPG游戏时,每通过一关就会自动把游戏状态存盘,如果某一关没过去,你还可以选择读取前一关的状态。有些时候,在打Boss之前,你会手动存盘,以便万一打Boss失败了,可以从最近的地方重新开始。Git也是一样,每当你觉得文件修改到一定程度的时候,就可以“保存一个快照”,这个快照在Git中被称为commit。一旦你把文件改乱了,或者误删了文件,还可以从最近的一个commit恢复,然后继续工作,而不是把几个月的工作成果全部丢失。

现在,我们回顾一下readme.txt文件一共有几个版本被提交到Git仓库里了:

版本1:wrote a readme file

Git is a version control system.
Git is free software.

版本2:add distributed

Git is a distributed version control system.
Git is free software.

版本3:append GPL

Git is a distributed version control system.
Git is free software distributed under the GPL.

当然了,在实际工作中,我们脑子里怎么可能记得一个几千行的文件每次都改了什么内容,不然要版本控制系统干什么。版本控制系统肯定有某个命令可以告诉我们历史记录,在Git中,我们用git log命令查看:

$ git log
commit 3628164fb26d48395383f8f31179f24e0882e1e0
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug :: + append GPL commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug :: + add distributed commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <askxuefeng@gmail.com>
Date: Mon Aug :: + wrote a readme file

git log命令显示从最近到最远的提交日志,我们可以看到3次提交,最近的一次是append GPL,上一次是add distributed,最早的一次是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就会把它们自动串成一条时间线。如果使用可视化工具查看Git历史,就可以更清楚地看到提交历史的时间线:

好了,现在我们启动时光穿梭机,准备把readme.txt回退到上一个版本,也就是“add distributed”的那个版本,怎么做呢?

首先,Git必须知道当前版本是哪个版本,在Git中,用HEAD表示当前版本(HEAD是一个指针),也就是最新的提交3628164...882e1e0(注意我的提交ID和你的肯定不一样),上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100

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

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

--hard参数有啥意义?这个后面再讲,现在你先放心使用。

看看readme.txt的内容是不是版本add distributed

$ cat readme.txt
Git is a distributed version control system.
Git is free software.

果然。

还可以继续回退到上一个版本wrote a readme file,不过且慢,然我们用git log再看看现在版本库的状态:

$ git log
commit ea34578d5496d7dd233c827ed32a8cd576c5ee85
Author: Michael Liao <askxuefeng@gmail.com>
Date: Tue Aug :: + add distributed commit cb926e7ea50ad11b8f9e909c05226233bf755030
Author: Michael Liao <askxuefeng@gmail.com>
Date: Mon Aug :: + wrote a readme file

最新的那个版本append GPL已经看不到了!好比你从21世纪坐时光穿梭机来到了19世纪,想再回去已经回不去了,肿么办?

办法其实还是有的,只要上面的命令行窗口还没有被关掉,你就可以顺着往上找啊找啊,找到那个append GPLcommit id3628164...,于是就可以指定回到未来的某个版本:

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

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

再小心翼翼地看看readme.txt的内容:

$ cat readme.txt
Git is a distributed version control system.
Git is free software distributed under the GPL.

果然,我胡汉三又回来了。

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

改为指向add distributed

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

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

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

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

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

小结

现在总结一下:

  • HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git reset --hard commit_id

  • 穿梭前,用git log可以查看提交历史,以便确定要回退到哪个版本。

  • 要重返未来,用git reflog查看命令历史,以便确定要回到未来的哪个版本。

摘录自:http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

Git -- 基本操作 之 版本回退的更多相关文章

  1. [原]git的使用(一)---建立本地仓库、add和commit、status和git diff、版本回退使用git reset

    在window下已经安装了git的环境 1.建立本地仓库 mkdir   test     #建立test目录 cd   test        #进入目录 git  init           # ...

  2. Git使用:版本回退

    在Git中,我们可以用 git log命令查看我们修改的历史记录 C:\Users\Administrator\Documents\GitHub\learngit [master]> git l ...

  3. 【Git学习笔记】初始化Git仓库和版本回退

    学习地址 http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 什么是版本库呢?版本库又 ...

  4. git中的版本回退

    git版本回退有两种情况,一种是从本地版本库中(head区)回退到某个版本,可以用命令 git reset --hard head^ 或git reset --hard head~x ,head指的是 ...

  5. Git秘籍:在 Git 中进行版本回退

    导读 在这篇文章中,你将学到如何查看项目中的历史版本,如何进行版本回退,以及如何创建 Git 分支以便你可以大胆尝试而不会出现问题.快来试试吧. 在你的 Git 项目的历史中,你的位置就像是摇滚专辑中 ...

  6. Git教程之版本回退(4)

    现在,我们已经学会了修改文件,然后把修改提交到Git版本库,现在再次修改readme.txt文件如下:

  7. Git 系列(四):在 Git 中进行版本回退

    在这篇文章中,你将学到如何查看项目中的历史版本,如何进行版本回退,以及如何创建 Git 分支以便你可以大胆尝试而不会出现问题. 在你的 Git 项目的历史中,你的位置就像是摇滚专辑中的一个片段,由一个 ...

  8. Git学习-Git时光机之版本回退(二)

    Git,是Linus花了两周时间用C写的一个分布式版本控制系统.牛人该怎么定义? 零.结论先行 倒叙总结一下: HEAD指向的版本就是当前版本,因此,Git允许我们在版本的历史之间穿梭,使用命令git ...

  9. Git分支和版本回退

    一.分支 1.分支简单介绍 简单使用: 可以将git branch new_branch和git checkout new_branch两个命令合并成一个命令: git checkout -b new ...

随机推荐

  1. 【转】【WebStorm】利用WebStorm来管理你的Github

    用webstorm上传代码时,首先要先下载git,网址一搜就可以搜到,然后开始配置webstorm,打开webstorm,在file-settings中直接搜索github,然后输入自己github的 ...

  2. RSS Reader in PC & iPhone

    PC上当然是用feedly web版.但出乎意料的是,iPhone上最好用的居然是safari版QQ邮箱...

  3. 【MyBean-开源框架】进行简单的逻辑插件(演示在控制台中应用)

    [说明] 很多时候大家认为客户端插件一般是窗体.其实不然,很多功能都可以看成是插件,比如一个单据的审批功能,一个单据上面,单价的获取功能,都可以看成是插件,然后后期通过配置,可以灵活进行切换.MyBe ...

  4. Git GUI中文乱码问题解决方法

    使用Git GUI的查看代码的时候,会出现中文乱码: 在乱码的区域点击鼠标右键,选择Encoding,然后选择Unicode(UTF-8),乱码问题解决:

  5. a,input,button点击的时候出现蓝色的边框

    a,button,input{ -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-user-modify: read-write-plain ...

  6. jsdoc注释规范工具(使用 JSDoc 3 自动生成 JavaScript API 文档)

    安装和使用规范见:http://moodpo.com/archives/jsdoc3-tutorial.html 实例: /** * 模块调用方法 * * * @param {string} modu ...

  7. 《Android 编程权威指南》读书总结

    1.当一段代码被多次使用,可将这段代码封装成一个抽象类,以后再要用到该段代码时,直接extends(继承)这个抽象类. 2.SDK版本向后兼容,即在SDK发布后推出的Android版本都可以使用该SD ...

  8. 5. 支持向量机(SVM)软间隔

    1. 感知机原理(Perceptron) 2. 感知机(Perceptron)基本形式和对偶形式实现 3. 支持向量机(SVM)拉格朗日对偶性(KKT) 4. 支持向量机(SVM)原理 5. 支持向量 ...

  9. pandas 常用函数整理

    pandas常用函数整理,作为个人笔记. 仅标记函数大概用途做索引用,具体使用方式请参照pandas官方技术文档. 约定 from pandas import Series, DataFrame im ...

  10. 地铁盾构管片姿态测量软件(Excel)

    记得11年刚开始从事盾构测量的时候,只知道搬站(倒站),测导线,还有就是测量管片.觉得最麻烦的就是在每个管片上面放个水平长尺,用全站仪测出他的水平位置和高程,但当时是本子记录每个数据,回去在敲到电脑上 ...