Git 如何撤销修改?

399 阅读2分钟

Git 有 4 个区:

  • 工作区(Working Area)
  • 暂存区(Stage)
  • 本地仓库(Local Repository)
  • 远程仓库(Remote Repository)

以及 5 种状态:

  • 未修改(Origin)
  • 已修改(Modified)
  • 已暂存(Staged)
  • 已提交(Committed)
  • 已推送(Pushed)

一套完整的命令流程如下所示:

git add . # 把文件放入暂存区
git commit -m "comment" # 把文件从暂存区提交进本地仓库
git push # 把文件从本地仓库推送进远程仓库

那如果想要撤销修改应该如何操作呢?首先得看一下是撤销哪个区的修改:

已修改,未暂存

只修改了文件,但没有执行 git add .,此时可以用 git diff 用于查看工作区和暂存区之间的差异,撤销命令为:

git checkout .
git reset --hard

git checkout .git add . 是站在同一个地方(修改文件之后)朝两个相反方向的操作,即如果想保存修改,就执行 git add . 让修改进入暂存区,如果想撤销修改,就执行 git checkout . 恢复原来的状态。

已暂存,未提交

已经执行了 git add .,但还没有执行 git commit,此时可以用 git diff --cached 看到暂存区和本地仓库之间的差异,撤销命令为:

git reset
git checkout .
# 或者
git reset --hard

git reset 会把修改退回到 git add . 之前的状态,也就是说文件本身还处于已修改未暂存状态,如果想退回未修改状态,还需要执行 git checkout .

已提交,未推送

既执行了 git add .,又执行了 git commit,这时候代码已经进入了本地仓库,此时可以用 git diff master origin/master 查看本地仓库和远程仓库之间的差异,撤销命令为:

git reset --hard origin/master

因为本地仓库已经被污染了,只能从远程仓库把代码取回来取代本地仓库。

已推送

git add 了,又 git commit 了,并且还 git push 了,这时代码已经进入远程仓库,由于本地仓库和远程仓库是等价的,只需要先恢复本地仓库,再强制 push 到远程仓库就好了:

git reset --hard HEAD^ # 回滚到前一个版本
git push -f

如果通过使用 git reset --hard 意外造成了代码丢失,可以通过 git reflog 查找这次撤销操作来找回丢失的代码。