协慌网

登录 贡献 社区

如何将 Git 存储库还原为先前的提交

如何从当前状态恢复为在某个提交时创建的快照?

如果我做git log ,那么我得到以下输出:

$ git log
commit a867b4af366350be2e7c21b8de9cc6504678a61b`
Author: Me <me@me.com>
Date:   Thu Nov 4 18:59:41 2010 -0400

blah blah blah...

commit 25eee4caef46ae64aa08e8ab3f988bc917ee1ce4
Author: Me <me@me.com>
Date:   Thu Nov 4 05:13:39 2010 -0400

more blah blah blah...

commit 0766c053c0ea2035e90f504928f8df3c9363b8bd
Author: Me <me@me.com>
Date:   Thu Nov 4 00:55:06 2010 -0400

And yet more blah blah...

commit 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Author: Me <me@me.com>
Date:   Wed Nov 3 23:56:08 2010 -0400

Yep, more blah blah.

如何从 11 月 3 日恢复提交,即提交0d1d7fc

答案

这很大程度上取决于 “恢复” 的含义。

暂时切换到其他提交

如果你想暂时回到它,傻瓜,然后回到你所在的位置,你所要做的就是检查所需的提交:

# This will detach your HEAD, that is, leave you with no branch checked out:
git checkout 0d1d7fc32

或者,如果你想在那里做出提交,那么在你做的时候继续做一个新的分支:

git checkout -b old-state 0d1d7fc32

要回到原来的位置,只需查看您再次访问的分支。 (如果你做了更改,就像转换分支时一样,你必须在适当的时候处理它们。你可以重置它们扔掉它们; 你可以藏匿,结账,存放 pop 以带走它们; 你可以提交如果你想要那里的分支,他们到那里的一个分支。)

硬删除未发布的提交

另一方面,如果你想真正摆脱自那时以来所做的一切,那么有两种可能性。一,如果您还没有发布任何这些提交,只需重置:

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts, if you've modified things which were
# changed since the commit you reset to.

如果你陷入困境,你已经抛弃了你的本地变化,但你至少可以通过重新设置来回到原来的位置。

使用新提交撤消已发布的提交

另一方面,如果您已发布作品,则可能不希望重置分支,因为这有效地重写了历史记录。在这种情况下,您确实可以还原提交。使用 Git,revert 有一个非常具体的含义:使用反向补丁创建一个提交以取消它。这样您就不会重写任何历史记录。

# This will create three separate revert commits:
git revert a867b4af 25eee4ca 0766c053

# It also takes ranges. This will revert the last two commits:
git revert HEAD~2..HEAD

#Similarly, you can revert a range of commits using commit hashes:
git revert a867b4af..0766c053 

# Reverting a merge commit
git revert -m 1 <merge_commit_sha>

# To get just one, you could use `rebase -i` to squash them afterwards
# Or, you could do it manually (be sure to do this at top level of the repo)
# get your index and work tree into the desired state, without changing HEAD:
git checkout 0d1d7fc32 .

# Then commit. Be sure and write a good message describing what you just did
git commit

git-revert实际上在其描述中涵盖了很多内容。另一个有用的链接是这个讨论 git-revert 的 git-scm.com 部分

如果您决定不想还原,则可以还原还原(如此处所述)或重置为还原之前(请参阅上一节)。

在这种情况下,您可能会发现此答案很有用:
如何将 HEAD 移回以前的位置? (独立头)

将工作副本还原为最近的提交

要恢复到先前的提交,请忽略任何更改:

git reset --hard HEAD

其中 HEAD 是当前分支中的最后一次提交

将工作副本还原为较旧的提交

要恢复到比最近提交更早的提交:

# Resets index to former commit; replace '56e05fced' with your commit code
git reset 56e05fced 

# Moves pointer back to previous HEAD
git reset --soft HEAD@{1}

git commit -m "Revert to 56e05fced"

# Updates working copy to reflect the new commit
git reset --hard

Credits 转到类似的 Stack Overflow 问题, 在 Git 中恢复为 SHA 哈希的提交?

这里有很多复杂而危险的答案,但实际上很简单:

git revert --no-commit 0766c053..HEAD
git commit

这将从 HEAD 返回到提交哈希的所有内容,这意味着它将在工作树中重新创建该提交状态, 就好像每次提交都已经被回退​​一样。然后,您可以提交当前树,它将创建一个全新的提交,基本上等同于您 “恢复” 的提交。

--no-commit标志允许 git 立即恢复所有提交 - 否则,系统会提示您为该范围内的每个提交发送一条消息,并使用不必要的新提交乱丢您的历史记录。)

这是回滚到以前状态安全且简单的方法 。没有历史被破坏,因此它可以用于已经公开的提交。