343

我正在尝试学习如何将文件和项目恢复或回滚到以前的状态,但不了解git revertcheckoutreset. 为什么看似相同的目的有 3 个不同的命令,什么时候应该选择一个而不是另一个?

4

7 回答 7

542

这三个命令的用途完全不同。他们甚至一点都不相似。

git revert

此命令创建一个新的提交,以撤消先前提交的更改。此命令向项目添加新历史记录(它不会修改现有历史记录)。

git checkout

此命令从存储库中签出内容并将其放入您的工作树中。它还可以具有其他效果,具体取决于调用命令的方式。例如,它还可以更改您当前正在处理的分支。此命令不会对历史记录进行任何更改。

git reset

这个命令稍微复杂一些。根据调用方式,它实际上做了几件不同的事情。它修改索引(所谓的“暂存区”)。或者它会更改分支头当前指向的提交。此命令可能会更改现有历史记录(通过更改分支引用的提交)。

使用这些命令

如果在项目历史的某个地方进行了提交,而您后来决定提交是错误的并且不应该完成,那么git revert该工具就是该工作的工具。它将撤消由错误提交引入的更改,并在历史记录中记录“撤消”。

如果您在工作树中修改了文件,但尚未提交更改,则可以使用git checkout该文件的新存储库副本签出。

如果您做出了提交,但没有与其他人共享它并且您决定不想要它,那么您可以使用git reset重写历史记录,使其看起来好像您从未进行过该提交。

这些只是一些可能的使用场景。还有其他命令在某些情况下可能有用,以上三个命令也有其他用途。

于 2011-12-02T14:43:33.850 回答
85

假设您有提交:

C
B
A

git revert B, 将创建一个撤消B.

git revert A, 将创建一个撤消更改的提交A,但不会触及更改B

请注意,如果 中的更改B依赖于 中的更改,则无法A恢复。A

git reset --soft A,将更改提交历史和存储库;暂存和工作目录仍将处于C.

git reset --mixed A,将更改提交历史、存储库和暂存;工作目录仍将处于C.

git reset --hard A,将更改提交历史、存储库、暂存和工作目录;你会回到A完全的状态。

于 2017-07-15T16:03:08.030 回答
30
  • git revert用于撤消先前的提交。在 git 中,您不能更改或删除较早的提交。(实际上你可以,但它可能会导致问题。)因此,revert 不是编辑早期的提交,而是引入了一个新的提交,它反转了早期的提交。
  • git reset用于撤消工作目录中尚未提交的更改。
  • git checkout用于将文件从其他提交复制到您当前的工作树。它不会自动提交文件。
于 2011-12-02T14:40:43.560 回答
25
  • git checkout修改你的工作树,
  • git reset修改您所指向的分支的引用,
  • git revert添加一个提交撤消更改。
于 2011-12-02T14:20:18.523 回答
7

重置 - 在提交级别,重置是一种将分支尖端移动到不同提交的方法。这可用于从当前分支中删除提交。

Revert - 还原通过创建新提交来撤消提交。这是撤消更改的安全方法,因为它没有机会重写提交历史记录。将此与 git reset 进行对比,后者确实会改变现有的提交历史。出于这个原因,应该使用 git revert 撤消公共分支上的更改,而 git reset 应该保留用于撤消私有分支上的更改。

您可以查看此链接 - 重置、结帐和还原

于 2015-11-18T10:06:12.640 回答
6

如果你破坏了树但没有提交代码,你可以使用git reset,如果你只想恢复一个文件,你可以使用git checkout.

如果您破坏了树并提交了代码,则可以使用git revert HEAD.

http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html

于 2011-12-02T14:16:53.367 回答
3

git restore我将尝试通过添加来回答问题

假设您有以下提交历史记录:

D
C
B
A

git revert

进行反向提交git revert commit-hash不会更改您的提交历史记录,但会进行新的提交,以还原作为提交的一部分提交的更改

git revert B, 将创建一个撤消B. Git历史帖子会是

reverse-B
D
C
B
A

如果提交C依赖于提交B git revert B将导致合并冲突

建议:git revert旨在恢复公共提交。所有其他撤消更改的方法都有可能更改提交历史,这可能会导致项目其他参与者出现问题。git revert是在不干预提交历史的情况下撤消更改的方法

git restore

git restore帮助您将文件从提交/暂存区移动到工作树/暂存区

命令是 git restore [--source=commit-hash] [--worktree] [--staged] [--] 文件

  • --worktree 表示恢复到工作树
  • --staged 表示恢复到 --staged。
  • 同时指定 --staged 和 --worktree 以从 --source 还原到工作树和暂存区域
  • 指定 --source 时,总是从源恢复
  • 当未指定 --source 并且给出 --staged 时,还原来自 HEAD
  • 当既没有指定 --source 也没有指定 --staged 时,恢复是从 staging-area 到 worktree

建议 - 用于git restore

  • 将 blob 提交到暂存区和/或工作树。
  • 暂存区到工作树

git checkout commit-hash

请注意,虽然有一个文件级实现git checkout可以帮助您将文件从提交中拉到暂存区或工作树中,但我们不会讨论它,因为现在这是git restore命令的责任,它的设计正是为了整理和制作一致的git checkout命令。

  • git checkout commit-hash- 头部被移动以指向提交哈希。总是让你处于分离的头部状态。
  • git checkout branch- 头部移动到指定的分支,现在不处于分离状态

建议:git checkout用来看看树周围的各种commit,并在分支之间切换

git reset commit-hash

  • 您处于分离的头部状态 -git reset将移动HEAD到指定的commit-hash. 就像git checkout commit-hash
  • 您没有处于分离的头部状态 -git reset会将整个移动(HEAD -> branch)到指定的位置commit-hash。如果这导致commits之前没有分支,那么这些提交将从 git 历史记录中删除

git reset也有三个选项--soft,,,--mixed。将您的工作树和索引(暂存区)移至不同的提交--hard后,您的工作树和索引(暂存区)应该如何?HEAD

  • --hard- 工作树和索引都匹配您移动到的新提交中的文件
  • --mixed(默认) - 工作树保持运行前的状态,git reset并且索引与您移动到的新提交中的文件匹配
  • --soft- 工作树和索引都保持在您运行之前的状态git reset

git reset在大多数情况下,可以使用git checkout,git branch -Dgit restore

建议:您是否进行了一些不应该进行的提交并且没有将更改推送到公共回购?最好只是让这些提交从未存在过?使用git reset. 如果您已将更改推送到公共存储库,那么如前所述,您希望使用git revert

于 2021-07-10T06:58:03.660 回答