Git 的各种回滚文件

3,828 阅读3分钟
原文链接: gaojingbao.me

在我们使用Git的过程中,总会在各种情况下需要各种回滚文件。而从本地的角度看,你的修改可能存在三块区域中,workspcace、index或者commit之后的历史对象区域。

workspace内的回滚

git checkout file1 (回滚单个文件)
git checkout file1 file2 ... fileN (一次回滚多个文件,中间用空格隔开即可)
git checkout .(直接回滚当前目录一下的所有workspace内的修改,会递归扫描当前目录下的所有子目录)

index内的回滚

这个过程一般被分为了两步:

  1. 将index区域中修改过的文件移除index,也就是恢复到workspace中。这部用git reset来解决。
  2. 一旦文件重新回到working tree中,回滚操作就是上面提到的git checkout

例如,我修改了a.txt和my_dir/b.txt,并将将他们加入了index区域
git add a.txt my_dir/b.txt
将当前目录及子目录内的所有修改移出index区域
git reset .
到这一步之后,就用上面提到git checkout就可以解决问题了。

修改最后一次commit的记录

很多时候回滚仅仅是因为自己最后一次commit漏掉一些修改,想要回滚这次commit之后再重新commit。只要在自满意了所有的修改之后,直接执行git commit –amend,就可以开启上次提交的“补救”提交模式,然后把你对上次所有漏掉的东西加上去就好了。
git commit -a --amend

回滚中间的某次提交

比如我想要回滚上图中倒数第二次提交,就是HEAD^那次,我们先通过git show HEAD^ 看看那次提交都干了啥?然后再通过git revert HEAD^来回滚这次操作
有冲突解决冲突,自己去编辑,去掉冲突范围标识符号,保存文件即可。然后按照git正常的流程再次提交,编辑提交的信息即可。

回滚最后的N次提交

在回滚commit的场景中,git reset的作用就是将当前的HEAD reset到你指定的那个分支。这个过程中最值得注意的就是你使用的参数。最常用的主要是

  • –soft(个人推荐使用这个,他不会修改你目前index或者workspace中所做的任何修改)/
  • –mixed(你在reset时不加任何参数时的默认行为,会默默把你在index中的修改给灭了!)/
  • –hard(这个是我绝的最危险的参数,会把你index和workspace中的所有修改毁灭的毛都不剩,使用之前请三思,这确实是你要的行为!)
    因此我推荐使用–soft参数
    git reset --soft HEAD~2
    git reset --mixed HEAD~2
    git reset --hard HEAD~2 //危险,慎用

从git reset的解释中,我们就可以看出,git reset是一个“斩断”式的回滚操作,因为你把当前的HEAD指针直接移动到了你需要回滚到的那次记录。而git本身的commit链条是逆向回溯的,所以你在提交历史里面再也找不到当前HEAD指向的commit之后的记录了。当然这种还是可以通过git reflog找到被斩断丢失的那些提交的。