上次是喝大了,写乱了一个文件a.c。如果这次喝大了写乱了多个文件怎么办(还提交了)?虽然git restore命令支持类似*.c的模式匹配一大批文件,但是我都喝大了,都不知道哪些文件搞乱了,也不愿意花时间一个个的比对了(因此也无法写出“文件模式*.c”),干脆我们就回退到上一个版本吧。这里和数据库的rollback不同,数据库在commit后,显然不能rollback了;GIT就可以回退版本。GIT使用一种叫做reset的命令回退版本。reset的意思是重新设置,重新设置什么?是重新设置的是分支的链表头指针。HEAD指针指向为一个叫较老的commit对象,显然后果就是stage区,和repo区的当前历史版本(以及work区)不一致了。这里涉及到三个区的一致性问题。前文说过,GIT在努力检测三个区的一致性,GIT reset命令有些参数,可以“自动化”的拉平一致性。当然,自动拉平一致性,肯定会造成修改内容的丢失。有些动作强烈一些,例如--hard方式(stage区和work区丢失全部最新修改),有些动作轻柔一些例如--soft方式。
例子:git reset HEAD~3 --soft # 将当前HEAD指向HEAD[3]这个位置
现在是最难的部分 参数:--hard --mixed --soft --merge --keep 这五种方式的区别。
GIT 参考手册给出示意图:
reset之前的状态 rest方式 reset之后的状态
working index HEAD target working index HEAD ---------------------------------------------------- A B C D --soft A B D --mixed A D D --hard D D D --merge (disallowed) --keep (disallowed)
working index HEAD target working index HEAD ---------------------------------------------------- A B C C --soft A B C --mixed A C C --hard C C C --merge (disallowed) --keep A C C
working index HEAD target working index HEAD ---------------------------------------------------- B B C D --soft B B D --mixed B D D --hard D D D --merge D D D --keep (disallowed)
working index HEAD target working index HEAD ---------------------------------------------------- B B C C --soft B B C --mixed B C C --hard C C C --merge C C C --keep B C C
working index HEAD target working index HEAD ---------------------------------------------------- B C C D --soft B C D --mixed B D D --hard D D D --merge (disallowed) --keep (disallowed)
working index HEAD target working index HEAD ---------------------------------------------------- B C C C --soft B C C --mixed B C C --hard C C C --merge B C C --keep B C C
怎么看这个图呢?假设某个文件(权且是a.c),内容状态是A或B或C或D(权且认为a.c文件中只有一个字符A)。target是reset最终把HEAD放到的commit对象。
--soft方式:你会发现reset前后,work区a.c原封未动,index区的a.c原封未动
--hard方式:work区和index区的a.c全被覆盖了,变成target版本的a.c了。三棵树的果子a.c一致了, 但是用户的临时工作成果和unstage工作成功(work区的修改)全丢了。
--mixed方式:比hard方式客气了一点,给你保留了work区的a.c,但是仍把index区的a.c覆盖了。
现在到了--merge方式:看图可知,当work,index,target的三个版本“一,一,不,同”,则禁止做reset。当work区和index不同时,work区的a.c被手下留情保留了。根据每个文件三个树状态,有的文件被hard处理,有的文件被soft处理。下面是原文:
这真是对英文水平和智商的挑战,我是看的一头雾水。这就是GIT学习曲线陡然上升的那一段。
--keep方式:基本看不懂