Git Revert,Checkout和Reset之间有什么区别?

haz*_*ziz 251 git git-revert git-checkout git-reset

我想了解如何重新恢复或回滚文件和项目到以前的状态,不明白之间的差别git revert,checkoutreset.为什么有3个不同的命令看似相同的目的,何时有人选择一个而不是另一个?

Dan*_*ing 436

这三个命令具有完全不同的目的.他们甚至没有相似之处.

git revert

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

git checkout

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

git reset

这个命令有点复杂.它实际上做了几件不同的事情,具体取决于它是如何被调用的.它修改了索引(所谓的"临时区域").或者它改变了当前指向分支头的提交.此命令可能会更改现有历史记录(通过更改分支引用的提交).

使用这些命令

如果在项目的历史记录中的某个位置进行了提交,并且您稍后认为提交是错误的并且不应该完成,那么这git revert是该工作的工具.它将撤消错误提交引入的更改,在历史记录中记录"撤消".

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

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

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

  • @BrunoSantos:烛台,铅管,匕首和绳子都可以用来谋杀人,但这并不意味着任何这些事情都特别相似. (14认同)
  • @Dan Mounlding - 实际上,有很多情况下`git reset`和`git checkout`可以做同样的事情.说它们"甚至不相似"并不仅仅是夸大其词:它甚至都不是真的.这两个命令可以做很多不同的事情,其中​​一些完全重叠.示例:`git reset --hard`和`git checkout - .`将执行完全相同的操作.从逻辑上讲,`git reset --hard <path>`和`git checkout <path>`也应该做同样的事情 - 然而git阻止你这样做.混淆这两个命令非常容易. (9认同)
  • 所以这三个命令可用于UNDO一些工作,这意味着它们不是那么"完全不同".相同的概念,不同的背景. (7认同)
  • @DanGordon我意识到我们可能会在这里产生不同意见.不过,我觉得我应该提供一些解释.你不能做`git reset --hard <path>`就像你可以`git checkout <path>`正是因为这两个命令做了*完全*不同的事情.`git reset`告诉Git将HEAD移动到另一个提交.另一方面,`git checkout`并不要求Git对HEAD做任何事情.它只留下HEAD而只是检出一个文件.是的,你可以用它们具有类似效果的方式制作它们.但他们实际上*做的*完全不同. (4认同)

Aka*_*all 32

假设你有提交:

C
B
A
Run Code Online (Sandbox Code Playgroud)

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完全的状态.

  • 如此直观的答案..结帐怎么样 (2认同)

Jon*_*han 29

  • git revert用于撤消先前的提交.在git中,您无法更改或删除先前的提交.(实际上你可以,但它可能会导致问题.)因此,revert不是编辑早期的提交,而是引入了一个新的提交,它反转了之前的提交.
  • git reset 用于撤消尚未进行调试的工作目录中的更改.
  • git checkout用于将文件从其他一些提交复制到当前工作树.它不会自动提交文件.

  • `git reset --soft`只重置HEAD,`git reset --hard`重置HEAD和你的工作目录. (9认同)
  • 我相信你对"git reset"错了."git reset"将您的HEAD重置为之前的一个提交,它不会重置您的工作目录.工作目录由"git checkout [filename]""重置" (6认同)

dan*_*rth 20

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

  • `git reset`**不只是修改分支指向**的提交,它还用于从索引中取消暂存文件,并且可以使用`git reset --mixed`(默认值)修改工作副本. (4认同)

fig*_*uts 11

我会尝试回答这个问题并git restore添加到它

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

D
C
B
A
Run Code Online (Sandbox Code Playgroud)

git revert

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

git revert B,将创建一个撤消 中更改的提交B。Git 历史帖子将会是

reverse-B
D
C
B
A
Run Code Online (Sandbox Code Playgroud)

如果 commitC依赖于 commitB 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 都没有指定时,恢复是从暂存区到工作树

建议 - 用于git restore从以下位置获取文件

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

git checkout commit-hash

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

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

建议:用于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

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

git reset大多数情况下可以使用 , 的组合来复制git checkoutgit branch -D除了git restore没有简单的方法来控制工作树和 stagin-area 的内容,除非你不使用 git reset

建议:您是否进行了一些不应该进行的提交,并且没有将更改推送到公共存储库?最好就好像这些提交从未存在过一样吗?使用git reset。如果您已将更改推送到公共存储库,那么正如前面所讨论的,您想要使用git revert


Sac*_*ngh 6

重置 - 在提交级别,重置是一种将分支的提示移动到另一个提交的方法.这可用于从当前分支中删除提交.

还原 - 通过创建新提交来还原撤消提交.这是撤消更改的安全方法,因为它无法重写提交历史记录.将此与git reset进行对比,这会改变现有的提交历史记录.因此,应使用git revert撤消公共分支上的更改,并且应保留git reset以撤消对专用分支的更改.

你可以看一下这个链接 - 重置,结账和还原


Los*_*can 5

如果您破坏了树但未提交代码,则可以使用git reset;如果您只想还原一个文件,则可以使用git checkout

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

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