Git 撤销修改的四种方法
在使用 Git 的过程中,我们难免会遇到撤销修改的场景。
例如,对不小心改坏的代码进行了 git add
甚至 git commit
操作,需要改回来。
或者,对修改结果不满意,要返回以前的某个版本。
难道我们只能删库重建吗?
答案是否定的。谷月老师带你一起学习 Git 撤销修改的四种方法。
1 撤销工作区文件的修改
当你把工作区中的代码改得一团糟,但是还没有 git add
,就可以采用以下两种方法之一,把工作区中的文件恢复到上一次 git add
或上一次 git commit
时的样子。
这两种方法的作用是一样的:都是用暂存区(索引、Stage)中的文件覆盖工作区(Working tree)中的同名文件;如果暂存区中的文件已经提交,那么就用 HEAD
中的文件覆盖工作区中的同名文件。
1.1 方法 1
操作命令:
1 |
|
1.2 方法 2
操作命令(需要 Git 2.23 以上):
1 |
|
1.3 例题
【例 1】我要撤销对 test.txt
文件的修改,恢复到上一次 git add
或上一次 git commit
时的样子。
1 |
|
2. 撤销暂存区文件的修改
如果已经 git add
,只要还没有 git commit
,那就还能补救。补救的方法,就是撤销暂存区文件的修改,换句话说,就是用版本库(默认是 HEAD
)中的同名文件覆盖暂存区中你要撤销修改的文件,但是不会影响工作区。
这个操作也就是 git add
的逆操作。
2.1 方法 1
操作命令:
1 |
|
完整形式:
1 |
|
其中,--mixed
表示用版本库中的文件覆盖暂存区中的同名文件,但是不会影响工作区;HEAD
就表示用 HEAD
中的文件覆盖暂存区中的同名文件。二者都是默认选项。
2.2 方法 2
操作命令(需要 Git 2.23 以上):
1 |
|
完整形式:
1 |
|
其中,--source HEAD
就表示用 HEAD
中的文件覆盖暂存区中的同名文件;-S
等价于 --staged
, 表示用版本库中的文件覆盖暂存区中的同名文件,但是不会影响工作区。二者都是默认选项。
2.3 例题
【例 2】刚才错误地暂存 test.txt
,需要撤销这次暂存。
1 |
|
3 简单粗暴,一次性撤销工作区和暂存区所有文件的修改
这个操作是从版本库中提取所有文件,一次性覆盖工作区中所有同名文件,并清空暂存区。
注意:是所有文件!!!
操作命令:git reset --hard
。
完整形式:git reset --hard HEAD
。其中 HEAD
就表示用 HEAD
中的文件覆盖工作区中的同名文件。
4 调取一个文件过去的版本
反复修改了好几个版本,但是都不如开头的版本好。总之,我们需要从过去的提交中,调取一个文件过去的版本。
4.1 方法 1
分两步走,先用 git reset
把这个文件从过去的某一次提交中提取出来,放进暂存区,再用 git chekcout
命令用暂存区中的这个文件覆盖工作区中的同名文件。
操作命令:
1 |
|
4.2 方法 2
用 git restore
一步到位。
操作命令(需要 Git 2.23 以上):
1 |
|
完整形式(需要 Git 2.23 以上):
1 |
|
其中 -s <commit-id>
等价于 --source <commit-id>
,把这个文件从过去的某一次提交中提取出来;-SW
等价于 --staged --worktree
二者同时使用,表示把这个从版本库中提取出来的文件,分别复制到暂存区和工作区,并覆盖工作区中的同名文件。
4.3 要回到最新版本怎么办?
操作命令:git reset --hard HEAD
这样,git
会从 HEAD 中提取所有文件,一次性覆盖工作区中所有同名文件,并清空暂存区。
4.4 例题
【例 3】调取第二次提交时的 test.txt,放进工作区。
1 |
|
或
1 |
|
5 总结
本文讲解了四种撤销修改的方法:撤销工作区文件的修改、撤销暂存区文件的修改、清空工作区和暂存区所有文件的修改,调取一个文件过去的版本。
6 知识扩展
回滚提交,我们可以用 git revert <commit id>
。之所以是“回滚”而不是“撤销”,是因为撤销不会留下提交记录,但是回滚会留下一次提交记录。
在不同的提交之间切换,我们可以用 git reset --hard <commit id>
。其中 --hard
可以根据情况改成 --soft
或者 --mixed
。
7 图片版权
题图:https://www.deviantart.com/black-pixel/art/Git-Wallpaper-Clean-357130508
头图:Image by Michael Pointner from Pixabay