Git Reset、Revert 和 Checkout 命令之间的区别

本文讨论了 git reset 、git revert 和 git checkout 命令之间的区别。 这些是一些最有用的 Git 实用程序,它们允许我们撤消存储库中的某些更改。

混淆这些命令很容易,但是到本文结束时,您将有信心使用上述命令来使用和浏览您的存储库。


Git Reset、Git Revert 和 Git Checkout 命令之间的区别

如果我们清楚每个命令对 Git 存储库的三个主要组件的影响,将更容易理解这些命令。

  1. 工作目录
  2. 暂存快照
  3. 提交历史 我们也可以将上述组件称为三棵树。

Git checkout

签出是什么意思?

此操作将 HEAD 指针重新定位到指定的提交。

Git Reset、Revert 和 Checkout 命令之间的区别

上图显示了 Git 存储库中的一系列提交。 HEAD 和主分支指针当前位于提交 d。

我们可以使用 git checkout 命令将我们的 HEAD ref 移动到任何提交。

例如,要将我们的 HEAD ref 移动到提交 b,我们将运行:

$ git checkout -b

我们可以在提交和文件级别使用 git checkout 命令。 在文件级别检出将使用指定提交的内容更新文件的内容。

Git revert

还原时,我们采用特定的提交并创建一个新的提交来反转指定提交的效果。 git revert commit 只在提交级别生效,不具备文件级别的功能。

Git reset

重置时,我们进行特定的提交,重置三棵树,并更新存储库以匹配指定提交时的存储库状态。 我们可以在对应于三棵树的三种不同模式下进行重置。

我们通常使用 git reset 和 git checkout 来撤消本地或私有更改。 它们都修改了存储库的历史,并且在推送到远程公共或共享存储库时可能导致冲突。


Git Reset vs. Git Revert vs. Git Checkout

下表给出了这三个命令的一些常见用例。

命令 范围 常见用例
git reset 提交级别 删除本地分支中的提交或丢弃未提交的更改。
git reset 文件级别 从索引中取消暂存文件。
git checkout 提交级别 检查旧提交并在分支之间切换。
git checkout 文件级别 丢弃工作目录中的更改。
git revert 提交级别 反转公共分支中提交的影响。
git revert 文件级别 (不适用)

提交级别操作

我们将参数传递给 git reset 和 git checkout 命令以调用不同级别的操作。 如果我们未能包含文件参数,则命令将作为一个整体对提交进行操作。

重置提交

在提交级别上重置会将 HEAD ref 移动到指定的提交。 我们可以使用此命令从分支中删除提交。

这是一个例子。

$ git reset HEAD~3

上面的命令会将我们分支的尖端向后移动三个提交。 我们可以将它们称为悬挂或孤立的提交。

我们已经丢弃了这三个提交。 最好使用该命令来取消我们尚未发布到远程共享存储库的提交。

我们还可以使用 git reset 命令通过传递以下标志之一来更改暂存快照和工作目录。

  1. –soft – 不更改暂存更改或工作目录。
  2. –mixed – 不影响工作目录,但会更改暂存快照以匹配指定的提交。
  3. –hard – 更改工作目录和暂存快照以匹配指定的提交。

签出旧提交

我们可以使用 git checkout 命令检查指定提交时的存储库状态。 我们还可以通过分支名称来在分支之间切换。

这是一个例子。

$ git checkout feature

上面的命令将切换到功能分支。 它不会四处移动分支。

我们还可以通过传递提交哈希或引用而不是分支名称来检查任意提交。 这是一个例子。

$ git checkout HEAD~1

上面的命令将检查我们当前提交的父级。 通过 HEAD~2 将检查祖父母。

上面的命令会将我们切换到分离的 HEAD 模式,因为我们当前的 HE****AD 没有分支引用。

一旦切换到另一个分支,将无法访问在分离 HEAD 模式下完成的所有更改和提交。 当您想在分离的 HEAD 状态下提交更改时,请始终创建一个新分支。

还原共享提交

当我们还原提交时,我们创建了一个新的提交来反转指定提交的效果。 这样,我们就避免了重写共享存储库的提交历史。

例如,如果我们想恢复最近的提交,我们将运行:

$ git revert HEAD

文件级操作

git checkout 和 git reset 命令接受文件路径作为可选参数。 这些命令的效果仅限于单个文件。

重置文件

我们可以更新文件的暂存快照以匹配指定提交的版本,如下所示。

$ git reset HEAD~1 README.md

上面的命令将获取当前提交的父提交中 README.md 文件的版本,并将其添加到下一次提交的索引中。 我们可以运行 git reset HEAD README.md 来取消暂存 README.md 文件。

Git 签出文件

将文件路径传递给 git checkout 命令会更新工作目录而不是暂存快照。 这不会在分支之间移动 HEAD 指针。

这是一个例子。

$ git checkout HEAD~1 README.md

这将从我们当前提交的父提交中获取 README.md 文件的版本,并仅更新我们工作目录中的 README.md 文件。 它只是意味着我们已经恢复到旧提交中的文件版本。

与撤销指定提交引入的更改的 git revert 命令不同,这会丢弃所有后续更改。 我们可以使用它来丢弃对单个文件的未暂存更改,如下所示。

$ git checkout HEAD README.md

总之,我们可以通过理解 e 来轻松区分 git reset 、git revert 和 git checkout 命令。每个命令对提交历史、暂存快照和工作目录的影响。