我正在尝试学习如何将文件和项目恢复或回滚到以前的状态,但不了解git revert
、checkout
和reset
. 为什么看似相同的目的有 3 个不同的命令,什么时候应该选择一个而不是另一个?
7 回答
这三个命令的用途完全不同。他们甚至一点都不相似。
git revert
此命令创建一个新的提交,以撤消先前提交的更改。此命令向项目添加新历史记录(它不会修改现有历史记录)。
git checkout
此命令从存储库中签出内容并将其放入您的工作树中。它还可以具有其他效果,具体取决于调用命令的方式。例如,它还可以更改您当前正在处理的分支。此命令不会对历史记录进行任何更改。
git reset
这个命令稍微复杂一些。根据调用方式,它实际上做了几件不同的事情。它修改索引(所谓的“暂存区”)。或者它会更改分支头当前指向的提交。此命令可能会更改现有历史记录(通过更改分支引用的提交)。
使用这些命令
如果在项目历史的某个地方进行了提交,而您后来决定提交是错误的并且不应该完成,那么git revert
该工具就是该工作的工具。它将撤消由错误提交引入的更改,并在历史记录中记录“撤消”。
如果您在工作树中修改了文件,但尚未提交更改,则可以使用git checkout
该文件的新存储库副本签出。
如果您做出了提交,但没有与其他人共享它并且您决定不想要它,那么您可以使用git reset
重写历史记录,使其看起来好像您从未进行过该提交。
这些只是一些可能的使用场景。还有其他命令在某些情况下可能有用,以上三个命令也有其他用途。
假设您有提交:
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
完全的状态。
git revert
用于撤消先前的提交。在 git 中,您不能更改或删除较早的提交。(实际上你可以,但它可能会导致问题。)因此,revert 不是编辑早期的提交,而是引入了一个新的提交,它反转了早期的提交。git reset
用于撤消工作目录中尚未提交的更改。git checkout
用于将文件从其他提交复制到您当前的工作树。它不会自动提交文件。
git checkout
修改你的工作树,git reset
修改您所指向的分支的引用,git revert
添加一个提交撤消更改。
重置 - 在提交级别,重置是一种将分支尖端移动到不同提交的方法。这可用于从当前分支中删除提交。
Revert - 还原通过创建新提交来撤消提交。这是撤消更改的安全方法,因为它没有机会重写提交历史记录。将此与 git reset 进行对比,后者确实会改变现有的提交历史。出于这个原因,应该使用 git revert 撤消公共分支上的更改,而 git reset 应该保留用于撤消私有分支上的更改。
您可以查看此链接 - 重置、结帐和还原
如果你破坏了树但没有提交代码,你可以使用git reset
,如果你只想恢复一个文件,你可以使用git checkout
.
如果您破坏了树并提交了代码,则可以使用git revert HEAD
.
http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html
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 -D
和git restore
建议:您是否进行了一些不应该进行的提交并且没有将更改推送到公共回购?最好只是让这些提交从未存在过?使用git reset
. 如果您已将更改推送到公共存储库,那么如前所述,您希望使用git revert