Git Revert、Checkout和Reset有什么区别?

dvtswwa3  于 2023-06-28  发布在  Git
关注(0)|答案(7)|浏览(145)

我正在尝试学习如何将文件和项目还原或回滚到以前的状态,并且不了解git revertcheckoutreset之间的区别。为什么有3个不同的命令用于看似相同的目的,什么时候应该有人选择一个?

3htmauhk

3htmauhk1#

这三个命令有着完全不同的目的。他们甚至一点也不相似。

git revert

此命令创建一个新的提交,该提交撤消上一个提交的更改。此命令将新的历史添加到项目中(它不会修改现有的历史)。

git checkout

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

git reset

这个命令有点复杂。它实际上做了几件不同的事情,这取决于它是如何被调用的。它修改索引(所谓的“暂存区”)。或者它改变了分支头当前指向的提交。此命令可以更改现有历史(通过更改分支引用的提交)。

使用这些命令

如果在项目历史中的某个地方进行了一次提交,并且您后来决定该提交是错误的,不应该这样做,那么git revert就是该工作的工具。它将撤销错误提交所带来的更改,并在历史记录中记录“撤销”。
如果您已经修改了工作树中的一个文件,但是还没有提交更改,那么您可以使用git checkout checkout 该文件的一个新的副本。
如果你已经提交了一个提交,但是没有和其他人分享,并且你决定不想要它,那么你可以使用git reset重写历史记录,这样看起来就像你从来没有提交过一样。
这些只是一些可能的使用场景。在某些情况下,还有其他一些有用的命令,上述三个命令也有其他用途。

ogq8wdun

ogq8wdun2#

假设你有commit:

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的状态。

bq9c1y66

bq9c1y663#

  • git revert用于撤消以前的提交。在git中,你不能修改或删除之前的提交。(实际上你可以,但是它可能会引起问题。)所以revert不是编辑之前的提交,而是引入一个新的提交来反转之前的提交。
  • git reset用于撤消尚未提交的工作目录中的更改。
  • git checkout用于将文件从其他提交复制到当前的工作树。它不会自动提交文件。
q5iwbnjs

q5iwbnjs4#

  • git checkout修改您的工作树,
  • git reset修改你所在分支指向的引用,
  • git revert添加一个提交撤消更改。
v1l68za4

v1l68za45#

**Reset -**在commit级别,reset是将分支的顶端移动到另一个commit的一种方式。这可以用来从当前分支中移除提交。
**Revert -**Revert通过创建新提交来撤消提交。这是一种安全的撤销更改的方法,因为它没有机会重写提交历史。与git reset相比,git reset会改变现有的提交历史。出于这个原因,git revert应该用于撤销公共分支上的更改,而git reset应该保留用于撤销私有分支上的更改。

你可以看看这个链接-Reset, Checkout and Revert

bogh5gae

bogh5gae6#

我将尝试在添加git restore的情况下回答问题
假设你有以下提交历史:

D
C
B
A
    • git revert**:

进行 * reverse-commit *。git revert commit-hash不会更改提交历史,但会进行一次新的提交,恢复作为提交一部分提交的更改
git revert B将创建一个提交,撤消B中的更改。Git history post it would be

reverse-B
D
C
B
A

如果提交C依赖于提交B,则git revert B将导致合并冲突
建议:git revert被设计为恢复公共提交。所有其他撤销更改的方法都有可能改变提交历史,这可能会导致项目其他参与者出现问题。git revert是在不干涉提交历史的情况下撤销更改的方法

    • git restore**:

git restore帮助您将文件从commit/staging-area移动到worktree/staging-area
命令是git restore [--source = commit-hash][--worktree][--staged][--] file

    • -worktree表示恢复到worktree
    • -staged表示恢复到--staged。
  • 同时指定--staged和--worktree以从--source还原到工作树和暂存区域
  • 指定--source时,始终从源进行恢复
  • 如果未指定--source,而指定了--staged,则从HEAD恢复
  • 如果既未指定--source也未指定--staged,则将从staging-area恢复到工作树

建议-使用git restore

  • 将blob提交到暂存区域和/或工作树。
  • 工作树分段区域
    • git checkout commit-hash**:

请注意,尽管有一个文件级的git checkout实现,它可以帮助你将提交的文件拉到暂存区或工作树中,我们将不讨论这个问题,因为现在这是git restore命令的责任,它被精确地设计为整理和保持git checkout命令的一致性。

  • git checkout commit-hash-Head被移动到commit-hash。总是让你处于一种超然的状态。
  • git checkout branch-Head被移动到指定的分支,现在它不处于分离状态

建议:使用git checkout查看树周围的各种提交并在分支之间切换

    • 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移到另一个提交时,你的工作树和索引(staging area)看起来应该是什么样子?

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

git reset在大多数情况下可以使用git checkoutgit branch -Dgit restore的组合来复制,除了没有简单的方法来控制工作树和stagin-area的内容,除非你不使用git reset。
建议:你是否做了一些不应该做的提交,并且没有将更改推送到公共存储库?是否最好就像这些提交从未存在过一样?使用git reset。如果您已经将更改推送到公共存储库,那么如前所述,您希望使用git revert

neekobn8

neekobn87#

如果你破坏了树但没有提交代码,你可以使用git reset,如果你只想恢复一个文件,你可以使用git checkout
如果你破坏了树并提交了代码,你可以使用git revert HEAD
http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html

相关问题