Git 撤销操作

学习视频:十分钟学会常用git撤销操作,全面掌握git的时光机

初始状态

  • Disk

    • Init
  • Staging(add)

    • Init
  • Local-git(commit)

    • Init
  • Remote-git(push)

    • Init

情况一

仅对文件做了修改但未add, 想要返回到初始状态

状态如下

  • Disk

    • Init — change
  • Staging(add)

    • Init
  • Local-git(commit)

    • Init
  • Remote-git(push)

    • Init

想要删除此修改, 只需使用以下命令, <filename>表示要恢复的文件名

1
2
3
git checkout <filename>
或者
git restore <filename>

操作后恢复到原始状态

  • Disk

    • Init~~ — change~~
  • Staging(add)

    • Init
  • Local-git(commit)

    • Init
  • Remote-git(push)

    • Init

情况二

若文件已经add

状态如下

  • Disk

    • Init — change
  • Staging(add)

    • Init — change
  • Local-git(commit)

    • Init
  • Remote-git(push)

    • Init
  1. 若仅取消暂存, 可以使用下面的命令恢复
1
2
3
git reset <filename>
或者
git restore --staged <filename>

此操作仅会把文件重暂存区取出, 不会删除修改

操作后恢复到以下状态

  • Disk

    • Init — change
  • Staging(add)

    • Init~~ — change~~
  • Local-git(commit)

    • Init
  • Remote-git(push)

    • Init
  1. 若想要连修改一起撤回, 使用以下命令
1
git checkout HEAD <filename>

HEAD表示最近的一次提交, 类似的HEAD~1表示倒数第二次提交

情况三

更改已经提交, 也就是如下状态

  • Disk

    • Init — change
  • Staging(add)

    • Init — change
  • Local-git(commit)

    • Init — change
  • Remote-git(push)

    • Init
  1. 此时要想仅取消此提交不撤销更改, 使用以下命令
1
git reset --soft HEAD~1

此时状态如下

  • Disk

    • Init — change
  • Staging(add)

    • Init — change
  • Local-git(commit)

    • Init—change
  • Remote-git(push)

    • Init
  1. 若想要将暂存一起取消, 则不使用--soft参数, 即
1
2
3
git reset HEAD~1
等价于
git reset --mixed HEAD~1

此时状态如下

  • Disk

    • Init — change
  • Staging(add)

    • Init — change
  • Local-git(commit)

    • Init—change
  • Remote-git(push)

    • Init
  1. 若想完全回到上一次提交(本提交的前一次), 文件的修改也完全恢复到该次提交的状态. 使用以下命令
1
git reset --hard HEAD~1

此时恢复到如下状态

  • Disk

    • Init — change
  • Staging(add)

    • Init — change
  • Local-git(commit)

    • Init—change
  • Remote-git(push)

    • Init

对于以上的恢复, 还有一种方式, 即在change的基础上加一个-change使文件在结果上恢复到上一次提交的状态

使用以下命令可以实现

1
git revert HEAD

效果如下

  • Disk

    • Init — change — -change == Init
  • Staging(add)

    • Init — change— -change
  • Local-git(commit)

    • Init—change— -change
  • Remote-git(push)

    • Init

此命令还可以用于撤销之前的某一次提交的修改

例如, 当前状态如下

  • Disk

    • Init — change1 —change2
  • Staging(add)

    • Init — change1 —change2
  • Local-git(commit)

    • Init — change1 —change2
  • Remote-git(push)

    • Init

使用如下命令, 撤销change1, <hash>指要撤销提交的hash值

1
2
3
git revert HEAD~1
或者
git revert <hash>

达到如下效果

  • Disk

    • Init — change1 —change2 —-change1
  • Staging(add)

    • Init — change1 —change2—-change1
  • Local-git(commit)

    • Init — change1 —change2—-change1
  • Remote-git(push)

    • Init

此命令在远程提交的撤销中起着重要作用, 见下文


情况四

修改已经push到了Github上

状态如下

  • Disk

    • Init — change
  • Staging(add)

    • Init — change
  • Local-git(commit)

    • Init — change
  • Remote-git(push)

    • Init — change
  1. 对于公有分支(不止一人使用该分支的情况), 只能使用revert
1
git revert HEAD

恢复到如下状态

  • Disk

    • Init — change — -change
  • Staging(add)

    • Init — change— -change
  • Local-git(commit)

    • Init—change— -change
  • Remote-git(push)

    • Init —change— -change
  1. 对于个人分支, resetrevert均可, 但若使用reset恢复了提交, 在push时需要加上-f
1
git push -f

-f表示强制, 在共有分支应避免使用, 或者禁止使用