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

发布于 2024-12-19 13:49:55 字数 152 浏览 2 评论 0原文

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

I am trying to learn how to restore or rollback files and projects to a prior state, and don't understand the difference between git revert, checkout, and reset. Why are there 3 different commands for seemingly the same purpose, and when should someone choose one over the other?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

美胚控场 2024-12-26 13:49:55

这三个命令具有完全不同的目的。它们甚至一点都不像。

git revert

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

git checkout

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

git reset

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

使用这些命令

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

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

如果您已进行提交,但尚未与其他人共享,并且您决定不想要它,那么您可以使用 git reset 重写历史记录,使其看起来像您从未做出过这样的承诺。

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

These three commands have entirely different purposes. They are not even remotely similar.

git revert

This command creates a new commit that undoes the changes from a previous commit. This command adds new history to the project (it doesn't modify existing history).

git checkout

This command checks-out content from the repository and puts it in your work tree. It can also have other effects, depending on how the command was invoked. For instance, it can also change which branch you are currently working on. This command doesn't make any changes to the history.

git reset

This command is a little more complicated. It actually does a couple of different things depending on how it is invoked. It modifies the index (the so-called "staging area"). Or it changes which commit a branch head is currently pointing at. This command may alter existing history (by changing the commit that a branch references).

Using these commands

If a commit has been made somewhere in the project's history, and you later decide that the commit is wrong and should not have been done, then git revert is the tool for the job. It will undo the changes introduced by the bad commit, recording the "undo" in the history.

If you have modified a file in your working tree, but haven't committed the change, then you can use git checkout to checkout a fresh-from-repository copy of the file.

If you have made a commit, but haven't shared it with anyone else and you decide you don't want it, then you can use git reset to rewrite the history so that it looks as though you never made that commit.

These are just some of the possible usage scenarios. There are other commands that can be useful in some situations, and the above three commands have other uses as well.

野却迷人 2024-12-26 13:49:55

假设您有提交:

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

Let's say you had commits:

C
B
A

git revert B, will create a commit that undoes changes in B.

git revert A, will create a commit that undoes changes in A, but will not touch changes in B

Note that if changes in B are dependent on changes in A, the revert of A is not possible.

git reset --soft A, will change the commit history and repository; staging and working directory will still be at state of C.

git reset --mixed A, will change the commit history, repository, and staging; working directory will still be at state of C.

git reset --hard A, will change the commit history, repository, staging and working directory; you will go back to the state of A completely.

你在看孤独的风景 2024-12-26 13:49:55
  • git revert 用于撤消先前的提交。在 git 中,您无法更改或删除较早的提交。 (实际上可以,但它可能会导致问题。)因此,恢复不是编辑较早的提交,而是引入了一个新的提交来反转较早的提交。
  • git reset 用于撤消工作目录中尚未提交的更改。
  • git checkout 用于将文件从其他提交复制到当前工作树。它不会自动提交文件。
  • git revert is used to undo a previous commit. In git, you can't alter or erase an earlier commit. (Actually you can, but it can cause problems.) So instead of editing the earlier commit, revert introduces a new commit that reverses an earlier one.
  • git reset is used to undo changes in your working directory that haven't been comitted yet.
  • git checkout is used to copy a file from some other commit to your current working tree. It doesn't automatically commit the file.
剩余の解释 2024-12-26 13:49:55
  • git checkout 修改您的工作树,
  • git reset 修改您所在分支的引用,
  • git revert 添加撤消更改的提交。
  • git checkout modifies your working tree,
  • git reset modifies which reference the branch you're on points to,
  • git revert adds a commit undoing changes.
单身情人 2024-12-26 13:49:55

我将尝试添加 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] [--] file

  • --worktree 意思是恢复到worktree
  • --staged 意味着 make恢复到--staged。
  • 同时指定 --staged 和 --worktree 以使从 --source 还原到工作树和暂存区域
  • 还原始终从源
  • 当指定 --source 时,当未指定 --source 和 --staged 时, 如果既没有指定 --source 也没有 --staged ,则恢复是从 HEAD 进行的
  • ,那么恢复是从暂存区到工作树

建议 - 使用 git Restore 将文件从

  • 提交 blob 带到暂存区和/或工作树。
  • staging-area 到工作树

git checkout commit-hash

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

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

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

git reset commit-hash

  • 您处于分离的 head 状态 - git reset 会移动 HEAD< /code> 到指定的提交哈希。就像 git checkout commit-hash 一样,
  • 您没有处于分离的 head 状态 - git reset 会移动整个 (HEAD -> 分支)到指定的commit-hash。如果这导致 commits 没有任何分支在前面,那么这些提交将从 git 历史记录中删除

git reset 还有三个选项 --soft--混合--hard。一旦您将 HEAD 移动到不同的提交,您的工作树和索引(暂存区域)应该是什么样子?

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

大部分情况下可以使用 git reset 进行复制git checkoutgit Branch -Dgit Restore 的组合,只是没有简单的方法来控制 worktree 和 stagin 的内容 -除非您不使用 git reset

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

I will try to answer the question with git restore added to it

Let's say you had the following commit history:

D
C
B
A

git revert:

Makes a reverse-commit. git revert commit-hash does not alter your commit history but makes a new commit that reverts the changes that were committed as part of the commit

git revert B, will create a commit that undoes changes in B. Git history post it would be

reverse-B
D
C
B
A

If commit C depends on commit B git revert B will result in a merge-conflict

Suggestion: git revert is designed to revert public commits. All the other ways to undo changes have the potential to alter commit history which might cause issues with other participants of the project. git revert is the way to undo changes without meddling with the commit history

git restore:

git restore helps you move files from commit/staging-area to worktree/staging-area

The command is git restore [--source=commit-hash] [--worktree] [--staged] [--] file

  • --worktree means make the restore to worktree
  • --staged means make the restore to --staged.
  • specify both --staged and --worktree to make the restore from --source to both the worktree and the staging-area
  • when --source is specified the restore is always from the source
  • when --source is not specified and --staged is given the restore is from the HEAD
  • when neither --source nor --staged are specified then the restore is from staging-area to the worktree

Suggestion - Use git restore to bring the files from

  • commit blob to staging-area and/or worktree.
  • staging-area to worktree

git checkout commit-hash:

please note that although there is a file-level implementation of git checkout which helps you pull files from commit into the staging area or worktree, we will not be discussing that since now that is the responsibility of the git restore command and it is designed precisely to declutter and make consistent the git checkout command.

  • git checkout commit-hash - Head is moved to point to the commit-hash. Always leaves you in a detached head state.
  • git checkout branch - Head is moved to point to the branch specified and this is now not in a detached state

Suggestion: Use git checkout to take a look at various commits around the tree and switch between branches

git reset commit-hash:

  • You were in a detached head state - git reset would move the HEAD to the specified commit-hash. Just like git checkout commit-hash
  • You were not in a detached head state - git reset would move the entire (HEAD -> branch) to the specified commit-hash. If this resulted in commits that no branch is ahead of then those commits are removed from git history

git reset also has three options --soft, --mixed, --hard. How should your worktree and Index(staging area) look like once you have moved your HEAD to a different commit?

  • --hard - Both the Worktree and the Index match the files in the new commit you moved to
  • --mixed (default) - Worktree remains as it was before you ran git reset and Index matches the files in the new commit you moved to
  • --soft - Worktree and Index both remain as they were before you ran git reset

git reset for the most part can be replicated using a combination of git checkout, git branch -D and git restore except that there is no easy way to control the contents of worktree and stagin-area as well except if you don't use git reset

Suggestion : Have you made a few commits that should not have been made and have not pushed the changes to the public repo? Is it best to just have as if these commits never existed? Use git reset. If you have pushed the changes to public repo then as discussed earlier you want to use git revert

空心空情空意 2024-12-26 13:49:55

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

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

你可以看看这个链接 -
重置、签出和恢复

Reset -
On the commit-level, resetting is a way to move the tip of a branch to a different commit. This can be used to remove commits from the current branch.

Revert -
Reverting undoes a commit by creating a new commit. This is a safe way to undo changes, as it has no chance of re-writing the commit history.
Contrast this with git reset, which does alter the existing commit history. For this reason, git revert should be used to undo changes on a public branch, and git reset should be reserved for undoing changes on a private branch.

You can have a look on this link-
Reset, Checkout and Revert

浴红衣 2024-12-26 13:49:55

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

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

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

If you broke the tree but didn't commit the code, you can use git reset, and if you just want to restore one file, you can use git checkout.

If you broke the tree and committed the code, you can use git revert HEAD.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文