阅读 1080

模拟面试官:Git 如何进行撤销操作?

在 Git 中,有三个命令可以用来撤销操作,分别是 git resetgit revertgit checkout

背景知识

Git 仓库由三个部分组成,工作区、暂存区和 Commit 历史。

我们在工作区进行开发,然后通过 git add 将文件修改添加到暂存区,然后 git commit 提交更改,就把暂存区的所有内容提交到了当前分支的 Commit 历史中去了。

git revert

该操作只能作用于 Commit,而不能作用于文件。同时,该操作会创建一个新的 Commit 来撤销之前提交的更改,它不会去修改现有的历史记录。

换句话说,这个命令是安全的,它不会丢失 Commit 记录,只会新增。

git reset

这个命令相对来说就要复杂一点了,它能够同时作用于 Commit 和文件,用来撤销还没有提交到远程仓库的改动。

对于 Commit 来说,git reset 会移动 HEAD 的位置,并且还可以变更暂存区和工作区,该操作有三个选项:

  1. --soft:该选项会修改 HEAD 位置,而工作区和暂存区不会有变化
  2. --mixed:默认选项,会修改 HEAD 位置以及暂存区,而工作区不会有变化
  3. --hard:修改 HEAD 位置,暂存区和工作区都会被更新到指定 Commit 的状态

是不是有点绕,没关系我们实战说话:

touch a
git add a
git commit 'feat: 添加 a 文件'
touch b
git add b
git commit 'feat: 添加 b 文件'
touch c
git add c
git commit 'feat: 添加 c 文件'
复制代码

现在,我们使用 git log 可以看到有三条 commit 记录,使用 git status 可以看到暂存区的状态为空。

接下来,我们使用 git reset HEAD~1 命令,然后我们再次使用 git loggit status 命令,可以看到 Commit 历史中,HEAD 的位置已经修改到了提交 b 的位置,同时在工作目录中我们还能找到 c 文件,并且 c 文件被移出了暂存区,这就是 mixed

接下来,我们再次将 c 文件提交回去恢复成初始状态,这次我们在命令后加上 --soft,我们再来看,HEAD 的位置依然被修改了,并且工作区 c 文件依然存在,不同的是 c 依然在暂存区中。

最后我们加上 --hard 再来看一看,我们可以发现,HEAD 变了,暂存区和工作区的 c 文件都被移除了,这个参数比较危险,也就不建议大家在公共分支上进行操作了。

说完了 Commit,那文件是如何撤销的呢?对于文件来说,上面提到的三个参数是不起作用的,它会去更新暂存区的对应文件到指定 Commit 的时候的版本。

还是上面的例子,如果我使用命令 git reset HEAD~1 c,会出现什么结果呢?大家可以想一想,答案是,它会将 c 文件更新到上一个 Commit 的时候的版本,也就是还没有被创建的状态,所以你执行 git status 可以发现暂存区中存在 delete: c,这就是文件的撤销。

git checkout

当你 checkout Commit 的时候,会将 HEAD 指向你指定的 Commit,并且这个没有分支指向这个 HEAD,所以 checkout 之后,会处于一个 detached HEAD 的分支,如果你要提交 Commit 到这个分支,你应该先 checkout 一个分支出来,然后再进行提交。

当你 checkout 文件的时候,checkout 命令和 reset 就有点类似,但是它不会更新暂存区,只会更新工作区,当你使用 git checkout <commit> <filename> 的时候,就会把工作区的对应文件更新到指定 Commit 版本的状态,当你使用 git checkout -- <filename> 的时候就会撤销掉在工作区这个文件的修改。

对于这些操作,大家一定要注意,不要乱用,把仓库搞乱了就不好了。

非常感谢您的阅读,欢迎关注、转发、分享支持我。

关注下面的标签,发现更多相似文章
评论