基本的命令含义参考:代码回滚:Reset、Checkout、Revert的选择
初始化一个空的测试目录:
1.撤销新增文件
1.1 还没有add
如果是新增的文件,还没有add提交到缓冲区,只是工作区做了修改,此时该文件是不受git管理的,所以直接修改或者删除该文件就好.
假如我们写了一个新的代码类A.java,然后还没有add提交,现在你后悔了,发现这个类没什么卵用,打算删除掉,那么,直接干掉就好,git也不会在意,反正它根本就不知道A.java的存在(Untracked)。
1.2 add了,但是还没有commit
假如你觉得A.java写的还有点意义,把它加入到缓存区,准备交由git管理:
刚add完,发现有个错误,或者又反悔了,不想add了,想从缓存区中拿出来,返回到没有add时的状态,那么,可以根据提示,使用下面的命令:
看,回到了没有add时的状态了。
如果你觉得A.java根本毫无存在价值,从缓存区拿出来之后就直接扔掉了,不需要恢复到add前的状态,而是直接删除,那么可以使用下面的命令:
看,A.java已经从这个世界消失了。
有人不服,说,我直接删除A.java不就好了:
可以看到,A.java确实也不见了。
但是仍然会看到有一个修改没有提交,在缓存区里发呆。
不仅如此,工作区多了一个为提交的修改,是delete: A.java。
由此看出,直接删除文件,相当于是一种新增的修改操作,而不是对之前git操作的撤销。
注意看提示,使用git add/rm <file>
命令将修改更新缓存区或者使用git checkout -- <file>
将修改撤销。
我们先试一下第一种:
提交修改之后,缓冲区也清净了。
再试试第二种:
看到,缓存区保持原样,A.java又回到了现实世界,撤销了上一次的文件删除修改。
1.3 commit了
如果自信满满的commit了,然后后悔了,想干掉。分两种情况:
第一种情况是,像例子里面这样,第一次提交,之前没有commit过,那如果想撤销本次提交,我还没想到方法。
只能去删除A.java,然后再来一次提交,第一次提交的黑历史无法抹去。
或者使用revert命令,通过一个新的提交,撤销某一次提交:
revert命令是撤销某一次提交,HEAD指的是最新的一次提交。
期间,会让你确认一下提交备注:
我们看到,上一次提交添加的A.java已经消失了,只是在git提交日志里面,能看到两条记录:
第二种情况是,非第一次提交,那么可以使用reset命令撤销提交,在下文中给出。
2.撤销修改
我们重新把A.java请回来,初始内容为hello
,然后做一次提交:
2.1 还没有add
老大说A.java有bug,需要修改,于是我们开始做每天最常见的游戏fix,将内容修改为world
:
修改完,可以看到提示,如果你觉得没问题,就add,这很正常~
但是,有一天脑袋不清醒,写了一大堆看不懂的代码,而且把原来的逻辑改的乱七八糟,现在唯一想做的就是把这些该死的代码删掉,恢复到上一次add或者commit的状态。
当然,你可以选择手动的删除,或者,使用提示中的命令:
意思就是,把A.java在工作区的修改全部撤销,这里有两种情况:
一种是A.java自修改后还没有被放到暂存区,现在,撤销修改就回到和版本库一模一样的状态(上一次commit);
一种是A.java已经add到暂存区后,又作了修改,现在,撤销修改就回到添加到暂存区后的状态(上一次add)。
2.2 已经add了,但是没有commit
信心满满的add了:
如果发现有问题,想把A.java从缓存区拿出来,可以使用提示命令:
现在,A.java回到了add前的状态。
注意,这里是对指定文件的撤回,参数--hard
是没用的(后面讲),因为该操作不会影响工作区,肯定会回到add前的状态,保留工作区修改。
如果想撤销工作区的修改,可以进一步使用上面的git checkout --<file>
命令。
3.3 已经commit了
如果已经commit了:
现在,如果想撤回这次提交,干掉黑历史,回到之前的某个提交版本,可以使用下面的方法:
看,代码回到了上一次提交,add前的状态。并且git log中,提交黑历史也不见了。
git reset
命令常用的参数包括三种:
- –soft – 缓存区和工作目录都不会被改变
- –mixed – 默认选项。缓存区和你指定的提交同步,但工作目录不受影响
- –hard – 缓存区和工作目录都同步到你指定的提交
把这些标记想成定义git reset
操作的作用域就容易理解多了。
这些标记往往和HEAD作为参数一起使用。比如,git reset --mixed HEAD
将你当前的改动从缓存区中移除,但是这些改动还留在工作目录中。另一方面,如果你想完全舍弃你没有提交的改动,你可以使用git reset --hard HEAD
。这是git reset最常用的两种用法。
关于回退版本:
查看提交历史,以便确定要回退到哪个版本:
查看命令历史,以便确定要回到未来的哪个版本:
版本更换
由于HEAD指向的版本就是当前版本,所以上一个版本就是HEAD^,上上个版本就是HEAD^^,当然往上100个版本写100个^比较容易数不过来,所以写成HEAD~100。