我们使用版本控制系统的原因之一,就是希望保存开发开始以来的各种修改,方便找回以前的代码,或去除错误修改。就算是一个人开发,如果没有版本控制系统,我开发进行到一个地方,发现方向不对,要回头时,只能再重新开发,或凭记忆修改代码到以前状态,那简直是噩梦。
本文专门介绍一下后悔药:reset,revert。
先讲一下版本,我们要恢复也要知道恢复到哪个版本,git不像svn有版本号,只有commit ID,就是那一串40位的十六进制字符串,为了方便操作,用HEAD代表最后一次提交,HEAD^表示HEAD的上次提交:
当然要表示从最后数第n次提交也可以用,HEAD~n:
如果只回退最近一次,可以:
git reset HEAD^
或者:
git revert HEAD
这两个效果是等价的,但实现是不同的:
git reset HEAD^
git revert HEAD
reset是直接把HEAD指向前一个版本,从log里看,没有最后一次提交了。
revert是把最后一次提交的修改撤销,再提交服务器,从log里看,多了一个回退提交,原提交也在。
还有,reset默认不修改工作区文件,回退后,工作区文件还是原来的,没回退。
如果加 --hard 会把工作区也回退。
revert默认就把修改合并提交的,出了冲突,才需求手工修改提交。
注意,只有对最后一次提交,他们才是等价的,reset作用是回卷,revert是撤销。
git reset HEAD~3
git revert HEAD~3
可以看到如果参数是一个版本,revert是只撤销这个版本作的修改,再合并提交。
而reset则是回退到这个版本,这个版本后的修改都丢掉。
如果从最终结果看,下面命令是等价的:
git reset HEAD~3
git revert HEAD~3..HEAD
revert后面 <版本a>..<版本b>,从<版本b>开始连续回退到<版本a>,但不包括<版本a>,实际也是一个版本一次的回退,每次都会让你输入提交注释。
分别执行上面指令,如果看log,会发现,reset后少了3个log,revert后多了3个log。
revert后如果不想撤销了,看一下log,reset回去就可以了。
reset后后悔了怎么办,没有log了!没关系,下面命令可以查到更多commit ID:
git reflog
再输入:
git reset <commit ID>
这个commit ID是上次reset前的ID,就可以回退会reset以前状态了。