版本回退
如果你不停的修改,然后有很多版本,可以用git log查看历史记录。git log命令显示从最近到最远的提交日志。
如果如果嫌输出信息太多,看得眼花缭乱的,可以试试加上--pretty=oneline参数。
$ git log --pretty=oneline
需要友情提示的是,你看到的一大串类似3628164...882e1e0的是commit id(版本号),和SVN不一样,Git的commit id不是1,2,3……递增的数字,而是一个SHA1计算出来的一个非常大的数字,用十六进制表示,而且你看到的commit id和我的肯定不一样,以你自己的为准。为什么commit id需要用这么一大串数字表示呢?因为Git是分布式的版本控制系统,后面我们还要研究多人在同一个版本库里工作,如果大家都用1,2,3……作为版本号,那肯定就冲突了。
在Git中,用HEAD表示当前版本,上一个版本就是HEAD^,上上一个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。
现在我要退回到上一个版本:
$ git reset --hard HEAD^
但是你会发现如果你有第1,2,3个版本,等你从第3个退回到第2个版本的时候,第3个版本用git log居然看不到了,只能看到第1和第2个版本。但是如果记得第3个版本的commit id,就能再回到第3个版本,比如第3个版本的commit id:390493dkaekfdak3344dd,只要:
$ git reset --hard 390493
版本号没必要写全,前几位就可以了,Git会自动去找。当然也不能只写前一两位,因为Git可能会找到多个版本号,就无法确定是哪一个了。
但是如果不记得这个commit id怎么办?Git提供了一个命令git reflog用来记录你的每一次命令:
$ git reflog
管理修改
你会问,什么是修改?比如你新增了一行,这就是一个修改,删除了一行,也是一个修改,更改了某些字符,也是一个修改,删了一些又加了一些,也是一个修改,甚至创建一个新文件,也算一个修改。
为什么Git比其他版本控制系统设计得优秀,因为Git跟踪并管理的是修改,而非文件。
为什么说Git管理的是修改,而不是文件呢?我们还是做实验。
第一步,对readme.txt做个修改。然后git add readme.txt添加,然后再修改readme.txt,最后再提交。
第一次修改 -> git add -> 第二次修改 -> git commit
然后发现,最后commit了第一次修改的文件,第二次修改的没有被提交。
这个时候要引入暂存区的概念。
其实git add这个命令是将修改的文件放入一个暂存区里面,而git commit只提交暂存区里面的东西。要是你没有用git add这个命令,修改就不起任何作用。
我们可以这样干,第二次修改才能提交。
第一次修改 -> git add -> 第二次修改 -> git add -> git commit
撤销修改
撤销修改可以分几种情况:
第一种:还没有git add到暂存区,只是在文件里面修改,可以用这个命令轻松搞定,撤销你的readme.txt修改:
$ git checkout -- readme.txt
git checkout -- readme.txt意思就是,把readme.txt文件在工作区的修改全部撤销
第二种:已经用git add到暂存区,但还没有commit提交。Git同样告诉我们,用命令git reset HEAD file可以把暂存区的修改撤销掉(unstage),重新放回工作区:
$ git reset HEAD readme.txt
git reset命令既可以回退版本,也可以把暂存区的修改回退到工作区。当我们用HEAD时,表示最新的版本。
然后我们再运行第一种情况的步骤:
$ git checkout -- readme.txt
第三种:已经commit到版本库了。这个时候就要用到上面用到过的版本回退:
$ git reset --hard HEAD^ 或者$ git reset --hard 390493
删除文件
比如要删除readme.txt这个文件,首先
$ git rm readme.txt
然后再再提交到版本库:
$ git checkout -- readme.txt
命令git rm用于删除一个文件。如果一个文件已经被提交到版本库,那么你永远不用担心误删,但是要小心,你只能恢复文件到最新版本,你会丢失最近一次提交后你修改的内容。