我正在尝试学习如何将文件和项目恢复或回滚到先前状态,并且不了解git revert
,checkout
和reset
之间的区别。为什么有3个不同的命令看似相同的目的,什么时候应该选择其中一个呢?
答案 0 :(得分:393)
这三个命令的用途完全不同。他们甚至没有相似之处。
git revert
此命令创建一个新提交,撤消先前提交的更改。此命令将新的历史记录添加到项目中(它不会修改现有历史记录)。
git checkout
此命令检出存储库中的内容并将其放入工作树中。它还可以具有其他效果,具体取决于命令的调用方式。例如,它还可以更改您当前正在处理的分支。此命令不会对历史记录进行任何更改。
git reset
这个命令有点复杂。它实际上做了几件不同的事情,具体取决于它是如何被调用的。它修改了索引(所谓的“临时区域”)。或者它改变了当前指向分支头的提交。此命令可能会更改现有历史记录(通过更改分支引用的提交)。
如果在项目的历史记录中某处进行了提交,并且您后来认为提交错误且不应该完成,则git revert
是该工作的工具。它将撤消错误提交引入的更改,在历史记录中记录“撤消”。
如果您已在工作树中修改了文件,但尚未提交更改,则可以使用git checkout
签出文件的新存储库副本。
如果您已提交,但尚未与其他任何人共享,并且您认为自己不想要它,那么您可以使用git reset
重写历史记录,使其看起来好像从未做了那个提交。
这些只是一些可能的使用场景。在某些情况下还有其他命令可用,而上述三个命令也有其他用途。
答案 1 :(得分:27)
git revert
用于撤消先前的提交。在git中,您无法更改或删除先前的提交。 (实际上你可以,但它可能会导致问题。)因此,revert不是编辑先前的提交,而是引入了一个新的提交,它反转了之前的提交。git reset
用于撤消尚未进行调整的工作目录中的更改。git checkout
用于将文件从其他提交复制到当前工作树。它不会自动提交文件。答案 2 :(得分:18)
git checkout
修改您的工作树git reset
修改您所指向的分支的引用,git revert
添加撤消更改的提交。答案 3 :(得分:17)
让我们说你有提交:
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
状态。
答案 4 :(得分:6)
重置 - 在提交级别,重置是一种将分支的提示移动到另一个提交的方法。这可以用于从当前分支中删除提交。
还原 - 通过创建新提交来还原撤消提交。这是撤消更改的安全方法,因为它无法重写提交历史记录。 将此与git reset进行对比,这会改变现有的提交历史记录。因此,应使用git revert撤消公共分支上的更改,并且应保留git reset以撤消对专用分支的更改。
您可以查看此链接 - Reset, Checkout and Revert
答案 5 :(得分:4)
如果您破坏了树但未提交代码,则可以使用git reset
,如果您只想恢复一个文件,则可以使用git checkout
。
如果您打破了树并提交了代码,则可以使用git revert HEAD
。
http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html
答案 6 :(得分:0)
我会尝试在问题中添加 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
帮助您将文件从 commit/staging-area 移动到 worktree/staging-area
命令是 git restore [--source=commit-hash] [--worktree] [--staged] [--] 文件
建议 - 使用 git restore
将文件从
git checkout commit-hash
:
请注意,虽然 git checkout
的文件级实现可以帮助您将文件从提交拉入暂存区或工作树,但我们不会讨论它,因为现在这是 {{ 1}} 命令,它的设计目的是使 git restore
命令保持一致。
git checkout
- 头部被移动到指向提交哈希。总是让你处于一种超然的头脑状态。git checkout commit-hash
- Head 被移动到指向指定的分支,现在不是处于分离状态建议:使用git checkout branch
查看树周围的各种提交并在分支之间切换
git checkout
:
git reset commit-hash
会将 git reset
移动到指定的 HEAD
。就像commit-hash
git checkout commit-hash
会将整个 git reset
移动到指定的 (HEAD -> branch)
。如果这导致 commit-hash
没有分支在前面,那么这些提交将从 git 历史记录中删除commits
也有三个选项 git reset
、--soft
、--mixed
。将 --hard
移动到不同的提交后,您的工作树和索引(暂存区)应该是什么样子?
HEAD
- 工作树和索引都与您移动到的新提交中的文件相匹配--hard
(默认)- 工作树保持您运行 --mixed
之前的状态,并且索引与您移动到的新提交中的文件相匹配git reset
- Worktree 和 Index 都保持您运行前的状态 --soft
git reset
大多数情况下可以使用 git reset
、git checkout
和 git branch -D
的组合进行复制,除了没有简单的方法来控制工作树的内容和stagin-area 也是如此,除非你不使用 git reset
建议:你是否做了一些不应该做的提交并且没有将更改推送到公共存储库?最好就好像这些提交从未存在过一样吗?使用git restore
。如果您已将更改推送到公共存储库,那么如前所述,您希望使用 git reset