写在前面:本文通过实例详细分析各种情况下使用 reset、checkout 达到撤销修改的效果。
1 - 引言
1.1 工作区、暂存区、分支之间的关系
没有 add 之前的文件都只在工作区中,add 之后文件将会添加到暂存区,commit 之后统一提交到分支,也就是更新本地版本库。
1.2 checkout 使用与效果
$ git checkout -- 文件名
可以将修改回退到最近一次 add
或者 commit
,但是只会修改文件内容,文件的提交状态不变,之前已经在暂存区的文件也仍旧在。(重要)
1.3 reset 使用与效果
# HEAD 表示本地版本库的最新版本
$ git reset HEAD -- 文件名
可以回退整个项目的版本,也可以回退将文件移出暂存区,撤销 add 动作。
2 - 应用场景
场景 1
某个文件被
add
添加到暂存区中,但突然发现有很大的纰漏,想要先把文件移出暂存区,以免被提交。
- 新建本地版本库,以及新建一个 test 的文本文件,文本内容如下:
- 随后 add 这个文件,并且查看状态,发现此文件已经被添加到暂存区,即将 commit。使用
reset
后,发现该文件已经被移出暂存区。
reset
可以将文件移出暂存区。(重要)
场景 2
文件还没添加到暂存区。 某个文件有重大纰漏或者已经改崩了,想要重新开始。因为此时还没有
add
添加到暂存区,我们当然可以直接在工作区手动将文件修改回去,但是能不能使用版本库里的版本直接回退。
- 修改 test 文本,添加了两行文本,查看与版本库文件的区别,绿色文字显示多了两行内容。
- 使用
checkout
回退。查看文件内容,发现文件内容已经与版本库一致,都只剩第一行,两者没有区别。
cheakout
可以对工作区的文件进行版本回退。(重要)
场景 3
文件已经添加到暂存区。添加到暂存区之后又对文件进行了一定的修改,此时想要撤销修改,回退到上一次
add
的状态。
-
先进行一次 test 文本修改,添加一行,并且 add 添加到暂存区。
-
先不提交,继续修改 test,再添加一行。
-
假如我们觉得第二次修改的内容(“+This is third line.”)有点多余,想要撤销,使用
checkout
。会发现内容已经回退了,而且回退内容是上一次add
之后的内容。
所以,对在暂存区的文件使用 checkout
可以返回上一次 add 的状态。(重要)
场景 4
文件已经添加到暂存区,想要修改暂存区的文件内容。
-
每一次
add
操作都会覆盖暂存区的内容,所以想要修改暂存区的内容可以直接使用add
覆盖。 -
同理,如果对文件进行了修改却不
add
,那么commit
提交的只会是暂存区的内容,修改部分只会留在工作区而得不到提交。(重要)
场景 5
整个项目需要版本回退。
git reset --hard HEAD^
就是回退到上一个版本,注意一个^
表示上一个版本,两个^
表示上两个版本。- 也可以指定回退到某一个版本,需要版本ID,
git reset --hard xxxxxx
,回退到版本xxxxxx。
3 - 总结
- 将文件移出暂存区,使用
reset
。 - 想要撤销修改内容,首先要判断文件状态,在工作区使用
checkout
会回退到版本库的版本;在暂存区使用checkout
会回退到上一次add
后的状态。注意,文件的状态不会改变,在暂存区的还是在暂存区,在工作区的还是在工作区。 - 假如需要回退项目的版本,需要使用
reset
。
正文结束,欢迎留言讨论。