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


7630

如何从当前状态恢复为特定提交时创建的快照?

如果我这样做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日恢复到提交,即commit 0d1d7fc



116
这是直接来自Github的关于撤消git中内容的非常清楚而透彻的文章
大雄2015年

3
相关:回滚到公共回购中的旧Git提交。请注意,该问题增加了回购协议是公开的约束。

58
我喜欢git,但是对于应该非常简单的东西有35个答案这一事实暴露了git的巨大问题。还是文档?
松饼人

2
语言中的“陷阱”在使用单词“ revert”作为口语含义时意味着如何,甚至在这里都没有解决过?到目前为止,6594投票而不是通过这种方式进行编辑,以强调差异吗?用“ committing”
一词

Answers:


9716

这在很大程度上取决于您所说的“还原”。

暂时切换到其他提交

如果您想暂时回到它,四处闲逛,然后回到自己的位置,您所要做的就是检查所需的提交:

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

或者,如果您想在该位置进行提交,请继续并在该位置创建一个新分支:

git checkout -b old-state 0d1d7fc32

要回到原来的位置,只需再次检查您所在的分支即可。(如果进行了更改,则像往常一样在切换分支时必须进行适当的处​​理。可以重置以将其丢弃;可以隐藏,签出,隐藏弹出以随身携带它们;可以提交如果您要在那儿有分支,请把它们送到那儿。)

硬删除未发布的提交

另一方面,如果您想真正摆脱之后的所有工作,则有两种可能性。一个,如果您尚未发布任何这些提交,只需重置:

# 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,还原具有非常特殊的含义:使用反向补丁创建提交以将其取消。这样,您就不会重写任何历史记录。

# 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-scm.com讨论git-revert的部分

如果您决定根本不希望还原,则可以还原该还原(如此处所述),也可以还原到还原之前的状态(请参阅上一节)。

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


118
@杆的评论git revert HEAD~3,以恢复最佳笏3提交是上午重要会议。
新亚历山大(Alexandria)

19
你能写出全部数字吗?像:git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
Spoeken

16
@MathiasMadsenStav是的,您当然可以通过完整的SHA1指定提交。我使用缩写的哈希值来使答案更易读,如果您要键入答案,则也倾向于使用它们。如果要复制和粘贴,请务必使用完整的哈希。有关如何命名提交的完整说明,请参见man git rev-parse中的指定修订
卡斯卡贝尔2012年

59
您可以使用git revert --no-commit hash1 hash2 ...,然后在一次提交中提交所有单个还原git commit -m "Message"
Mirko Akov

6
在这种情况下,“发布”是什么意思?
Howiecamp 2014年

1846

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

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

这会将所有内容从HEAD还原回提交哈希,这意味着它将在工作树中重新创建该提交状态,就好像回溯了所有提交以来。然后,您可以提交当前树,它将创建一个全新的提交,该提交基本上等同于您“还原”到的提交。

(该--no-commit标志可让git一次还原所有提交-否则,系统会提示您输入该范围内每个提交的消息,从而在历史记录中添加不必要的新提交。)

这是回滚到先前状态安全,简便的方法。历史记录不会被销毁,因此可以用于已公开的提交。


23
如果您确实确实希望有单独的提交(而不是通过一个大的提交来还原所有内容),则可以传递--no-edit而不是--no-commit,这样您就不必为每个还原都编辑提交消息。

87
如果0766c053..HEAD之间的提交之一是合并,则将弹出错误(与-m无关)。这可能会帮助那些遭遇是:stackoverflow.com/questions/5970889/...
timhc22

7
提交前查看差异git diff --cached
约翰·埃克

21
$ git revert --no-commit 53742ae..HEAD返回fatal: empty commit set passed
Alex G'8

10
@AlexG,这是因为您需要在要返回的哈希值之前输入哈希值。就我而言,哈希值就像:(81bcc9e HEAD{0}; e475924 HEAD{1}, ...来自git reflog),我想撤消我所做的工作81bcc9e,然后我必须做git revert e475924..HEAD
EpicPandaForce

1610

流氓编码器?

自己工作,只想工作吗?请按照下面的说明进行操作,它们已经为我和许多其他人可靠地工作了多年。

与他人合作?Git很复杂。在您轻率做某事之前,请阅读此答案下面的评论。

将工作副本还原为最新提交

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

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

积分会转到类似的堆栈溢出问题,还原为Git中SHA哈希的提交?


33
我做到了,但是后来我无法提交并推送到远程存储库。我希望特定的较早提交成为HEAD ...
Lennon 2012年

7
这意味着您已经推送了要还原的提交。对于已经签出您的代码并对其进行处理的人员,这可能会带来很多问题。由于他们无法将您的承诺顺利应用到他们的承诺上。在这种情况下,最好还原git。如果您是使用回购协议的唯一人。做一个git push -f(但是在做之前请三思)
vinothkr

6
我还想指出,或者对于软重置解决方案,您可以先进行硬重置,而不是先进行混合重置然后再进行硬重置,如下所示:git reset --hard 56e05fc; git reset --soft HEAD@{1}; git commit

5
@nuton linus对git的创建者pauling提出批评,称其过于复杂。他在记录中说,由于其复杂性,他被“震惊” git变得如此受欢迎
boulder_ruby 2015年

5
@boulder_ruby我认为您的意思是Linus Torvalds是git的创建者。但是我认为Linus Pauling可能会同意git很复杂。
Suncat2000

215

对我以及其他人而言,最好的选择是Git reset选项:

git reset --hard <commidId> && git clean -f

这对我来说是最好的选择!简单,快速,有效!


**注意:**如注释中所述,如果您要与拥有旧提交副本的其他人共享分支,则不要这样做

同样从评论中,如果您想要一种不太“笨拙”的方法,则可以使用

git clean -i

37
强制性警告:如果要与拥有旧提交副本的其他人共享分支,则不要执行此操作,因为使用这样的硬重置将迫使他们不得不将其工作与新重置的分支重新同步。有关详细说明如何安全地还原提交而不导致硬重置而丢失工作的解决方案,请参见此答案

7
我第二次@Cupcake警告...要非常注意后果。但是请注意,如果您真正需要使这些提交永久从历史记录中消失,则此reset + clean方法将做到这一点,并且您需要强制将修改后的分支推回任何远程。
ashnazg 2014年

5
git clean -f危险危险
Tisch

2
这会将本地副本的头部设置为所需的提交。但是后来我无法推动任何更改,因为它位于遥控器的后面。而且,如果我从远程拉出,它将最终返回到远程分支上最新提交的位置。如何完全(从任何地方)消除本地推送上已提交的几次提交?
阿德(Ade)

2
@Ade ..您可以使用该git push -f标志..但是要小心,它会覆盖遥控器。.确保您知道要做什么。
Pogrindis

176

在回答之前,让我们添加一些背景,解释一下这HEAD是什么。

First of all what is HEAD?

HEAD只是对当前分支上当前提交(最新)的引用。HEAD在任何给定时间(除外git worktree)只能有一个。

的内容HEAD存储在内部.git/HEAD,并且包含当前提交的40个字节的SHA-1。


detached HEAD

如果您不在最新的提交上-这意味着HEAD指向历史上的先前提交,则称为detached HEAD

在此处输入图片说明

在命令行上,它看起来像这样-SHA-1而不是分支名称,因为HEAD并不指向当前分支的尖端:

在此处输入图片说明


有关如何从分离的HEAD中恢复的几种选择:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

这将签出指向所需提交的新分支。该命令将签出给定的提交。

此时,您可以创建一个分支,并从此开始工作:

# Checkout a given commit.
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# Create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

您也可以随时使用refloggit reflog将显示任何更新的更改,HEAD并签出所需的reflog条目,将HEAD后退设置为此提交。

每次修改HEAD时,都会在 reflog

git reflog
git checkout HEAD@{...}

这将使您回到所需的提交

在此处输入图片说明


git reset HEAD --hard <commit_id>

将您的头“移动”回所需的提交。

# 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 2.7开始),您也可以使用git rebase --no-autostash

该模式说明了哪个命令可以执行什么操作。如您所见,reset && checkout修改HEAD

在此处输入图片说明


6
的绝佳提示git reflog,这正是我所需要的
smac89

4
哎哟! 这一切似乎都非常复杂...难道没有一个简单的命令会让您退后一步吗?就像从项目中的1.1版本回到1.0版本一样?我期望像这样:git
stepback_one_commit

有:git reset HEAD^
CodeWizard

3
@Kokodoko是的,这非常复杂……这是专家对刚起步的人很少考虑的一个完美例子。请参考我的答案,也请参考我推荐的书。Git并非您只能凭直觉就能掌握的东西。我可以肯定地说CodeWizard没有这样做。
麦克啮齿动物

145

如果要“取消提交”,擦除最后的提交消息,然后将修改后的文件放回暂存中,则可以使用以下命令:

git reset --soft HEAD~1
  • --soft表示未提交的文件应保留为工作文件,否则将被--hard丢弃。
  • HEAD~1是最后一次提交。如果要回滚3次提交,可以使用HEAD~3。如果要回滚到特定的修订版号,也可以使用其SHA哈希值来完成。

在您执行错误的操作并且您要撤消上一次提交的情况下,这是一个非常有用的命令。

资料来源:http//nakkaya.com/2009/09/24/git-delete-last-commit/


3
这是柔软而温和的:如果您不做任何工作,则可以免费冒险
nilsM

124

您可以通过以下两个命令执行此操作:

git reset --hard [previous Commit SHA id here]
git push origin [branch Name] -f

它将删除您之前的Git提交。

如果要保留更改,也可以使用:

git reset --soft [previous Commit SHA id here]

然后它将保存您的更改。


2
我在这篇文章中尝试了1/2打的答案,直到我明白了所有其他答案,我的git config在尝试推送时一直给我一个错误。这个答案有效。谢谢!
Gene Bo

对我来说,一个细节是我丢失了差异..我想继续看一下我在提交中所做的事情没有奏效。所以下一次,我将在发出此重置命令之前保存该数据
Gene Bo

1
这是我撤消错误合并的唯一方法,在这种情况下,还原不起作用。谢谢!
Dave Cole

最佳答案。谢谢
Imran Pollob

最佳答案,谢谢。
user1394

114

我尝试了很多方法来还原Git中的本地更改,并且如果您只想还原到最新的提交状态,这似乎是最好的方法。

git add . && git checkout master -f

简短的介绍:

  • 它不会创建任何提交git revert
  • 它不会像您一样分离您的HEAD git checkout <commithashcode>
  • 自分支中的最后一次提交以来,它将覆盖您的所有本地更改并删除所有添加的文件。
  • 它仅适用于分支名称,因此您只能以这种方式还原到分支中的最新提交。

我发现了一种更方便,更简单的方法来实现上述结果:

git add . && git reset --hard HEAD

HEAD指向您当前分支的最新提交。

这是相同的代码,代码boulder_ruby建议,但我已经加入git add .之前 git reset --hard HEAD删除的所有新建文件自上次提交,因为这是大多数人的期待,我相信恢复到最新提交的时候。


83

好的,返回上一个在Git中的提交非常容易...

还原但不保留更改:

git reset --hard <commit>

恢复并保留更改:

git reset --soft <commit>

说明:使用git reset,您可以重置为特定状态。如上所示,将其与提交哈希一起使用是很常见的。

但是,您看到的区别是使用两个标志--soft--hard,默认情况下git reset使用--soft标志,但这是始终使用标志的一种好习惯,我将解释每个标志:


- 柔软的

所说明的默认标志(不需要提供该标志)不会更改工作树,但是会添加所有准备提交的已更改文件,因此您将返回到提交状态,即对文件的更改将被取消登台。


- 硬

小心此标志。它将重置工作树,对跟踪文件的所有更改都将消失!


我还创建了下面的图像,在使用Git的现实生活中可能会发生这种情况:

Git重置为提交


的默认git reset值为git reset --mixed,不是git reset --soft。请检查git reset --mixed,-soft和--hard有什么区别?用简单的英语,什么是“混帐重置”吗?
Fabio说恢复莫妮卡

70

假设您在谈论master以及该分支上的内容(也就是说,这可能是您关心的任何工作分支):

# Reset local master branch to November 3rd commit ID
git reset --hard 0d1d7fc32e5a947fbd92ee598033d85bfc445a50

# Reset remote master branch to November 3rd commit ID
git push -f origin 0d1d7fc32e5a947fbd92ee598033d85bfc445a50:master

我在博客文章中找到了答案(现已不存在)

请注意,这是“重置并强制更改到遥控器”,因此,如果团队中的其他人已经被git pull了,则会给他们带来麻烦。您正在破坏变更历史记录,这是人们首先使用git的重要原因。

最好使用还原(请参阅其他答案)而不是重置。如果您是一个单人团队,那么这可能并不重要。


6
这个答案与其他答案有什么不同?
Matsmath's

那真不幸。我给博客写了电子邮件-希望他还可以!
markreyes


2
有关如何解决此问题的大多数其他建议都缺少推送语法。很棒。
jpa57

61

假设您在名为~/commits-to-revert.txt(我曾经git log --pretty=oneline获得过它们)的文本文件中进行了以下提交

fe60adeba6436ed8f4cc5f5c0b20df7ac9d93219
0c27ecfdab3cbb08a448659aa61764ad80533a1b
f85007f35a23a7f29fa14b3b47c8b2ef3803d542
e9ec660ba9c06317888f901e3a5ad833d4963283
6a80768d44ccc2107ce410c4e28c7147b382cd8f
9cf6c21f5adfac3732c76c1194bbe6a330fb83e3
fff2336bf8690fbfb2b4890a96549dc58bf548a5
1f7082f3f52880cb49bc37c40531fc478823b4f5
e9b317d36a9d1db88bd34831a32de327244df36a
f6ea0e7208cf22fba17952fb162a01afb26de806
137a681351037a2204f088a8d8f0db6e1f9179ca

创建一个Bash shell脚本以还原它们每个:

#!/bin/bash
cd /path/to/working/copy
for i in `cat ~/commits-to-revert.txt`
do
    git revert $i --no-commit
done

这会将所有内容恢复到以前的状态,包括文件和目录的创建以及删除,将其提交到分支并保留历史记录,但是您将其恢复到相同的文件结构。为什么Git没有a git revert --to <hash>在我之外。


41
你可以做一个git revert HEAD~3去除最后3个提交
罗德

25
@Rod-不,那是不对的。该命令将还原作为HEAD的第三个祖父母的提交(而不是最后三个提交)。
kflorence 2012年

1
@kflorence好,谢谢您的信息。会git revert -n master~3..master~1工作吗?(从kernel.org/pub/software/scm/git/docs/git-revert.html可以看到)
Rod

3
@Rod-听起来不错,虽然不是很丑陋的语法吗?我总是发现签出我要“还原”的提交,然后更加直观地提交。
kflorence

7
与使用这样的脚本相比,现在有一种更简单的方法,只需使用即可git revert --no-commit <start>..<end>,因为git revert在新(或全部?)Git版本中接受提交范围。请注意,范围的开始不包括在还原中。

58

Jefromi解决方案的其他替代方案

Jefromi的解决方案绝对是最好的解决方案,您绝对应该使用它们。但是,为了完整起见,我还想展示这些其他可替代的解决方案,这些解决方案也可用于还原提交(从某种意义上讲,就像创建一个新的提交一样,它撤消了先前提交中的更改git revert)。

需要明确的是,这些替代方法不是还原提交的最佳方法Jefromi的解决方案是,但是我只想指出,您还可以使用这些其他方法来实现与相同的目的git revert

选择1:硬复位和软复位

这是Charles Bailey解决方案的略微修改版本,用于还原到Git中SHA哈希的提交?

# Reset the index to the desired commit
git reset --hard <commit>

# Move the branch pointer back to the previous HEAD
git reset --soft HEAD@{1}

# Commit the changes
git commit -m "Revert to <commit>"

这基本上是通过使用以下事实而起作用的:软重置将在索引/分段区域中保留上一步提交的状态,然后您可以提交该状态。

备选方案2:删除当前树并替换为新树

该解决方案来自svick的Checkout旧提交并使之成为新提交的解决方案:

git rm -r .
git checkout <commit> .
git commit

与替代方法#1类似,这将复制<commit>当前工作副本中的状态。首先必须这样做,git rm因为git checkout不会删除自以来添加的文件<commit>


关于替代方案1,一个简单的问题:这样做,我们不会在两次提交之间松懈,对吗?
Bogac

2
@Bogac-点表示文件路径,在本例中为当前目录,因此假定您从工作副本的根目录运行它。
汤姆(Tom)

答案中多次重复警告,但有人可以补充一下为什么不是最好的方法吗?与git revert HEAD~2..HEAD@Cascabel(@ Jefromi's)链接解决方案中的方法相比,这是最好的方法。我没看到问题。
约书亚·戈德堡

55

这是返回上一次提交的一种更简单的方法(让它处于未提交状态,可以根据需要进行处理):

git reset HEAD~1

因此,不需要提交ID等:)


没用,这会产生一个git pull:错误:您对以下文件的本地更改将被merge覆盖:
malhal 2016年

1
@malhal这是因为您有未提交的更改。存储/重置它们,然后它将正常工作而不会出现该错误。
Paul Walczewski

39

有一个命令(不是核心Git的一部分,但是在git-extras包中)专门用于还原和暂存旧提交:

git back

对于手册页,它也可以这样使用:

# Remove the latest three commits
git back 3

37

最好的方法是:

git reset --hard <commidId> && git push --force

这会将分支重置为特定的提交,然后将使用与本地相同的提交上载远程服务器(这将在该特定的提交之后完全限制命令)

请注意,该--force标志会删除选定提交之后的所有后续提交,而没有恢复它们的选项。


3
像魅力一样工作!
Gaurav Gupta

我downvoted,因为我看不到你的答案如何提供例如尚未给出任何新的信息stackoverflow.com/a/37145089/1723886stackoverflow.com/a/27438379/1723886stackoverflow.com/a/48756719/1723886。实际上,大多数提交都已经提到git reset --hard,还有更多提到使用--force或-f来推送。
Alex Telon

它仅需一个命令即可完成工作,清晰而简单。如果您不喜欢我的答案,您可以随意投票。
david.t_92

1
将来考虑的另一种选择是建议对较早的答案进行编辑或添加评论,例如“也可以通过使用&&在一行中完成此操作”。这样,每个人都可以在一处看到改进的答案。
Alex Telon

36

完成所有更改后,按所有这些命令时,可能必须使用:

git push -f ...

而且不仅如此git push


15
强制性警告:如果您要与拥有旧提交副本的其他人共享分支,则不要这样做,因为使用这种强制推送将迫使他们不得不重新同步他们的工作。有关详细说明如何安全地还原提交而不用强制推动丢失工作的解决方案,请参见此答案

3
有时这就是您想要的。示例:提交并推送了几次提交到错误的分支(分支A)。在选择分支B之后,我希望将这些提交从分支A中删除。我不想还原,因为稍后将在分支A和B合并在一起时应用还原。做一个复位-硬<的commitid>分支A,接着为力推动,同时保留他们的分支B.我可以逃脱这个,因为我知道其他人是在分支A.发展从分支删除这些提交
道格- [R

谢谢!我不知道如何使远程分支与我的本地分支相匹配,只需要执行强制推送即可。
Mido

32

您可以自己完成所有这些初始步骤,然后返回到Git存储库。

  1. 使用git pull --all命令从Bitbucket中提取存储库的最新版本。

  2. -n 4从您的终端运行Git log命令。从后面的数字-n确定日志中从本地历史记录中的最新提交开始的提交数量。

    $ git log -n 4
    
  3. 使用git reset --hard HEAD~NN 重置存储库历史记录的开头,其中N是要收回的提交次数。在下面的示例中,将头部设置为一次提交,直到存储库历史记录中的最后一次提交:

  4. 使用git push --force强制将更改推送到Git存储库。

如果您希望Git存储库到先前的提交:

git pull --all
git reset --hard HEAD~1
git push --force


28

选择所需的提交,并通过以下方式进行检查

git show HEAD
git show HEAD~1
git show HEAD~2 

直到获得所需的提交。要使HEAD指向该位置,请执行

git reset --hard HEAD~1

git reset --hard HEAD~2或什么的。


7
强制性警告:如果要与拥有旧提交副本的其他人共享分支,则不要执行此操作,因为使用这样的硬重置将迫使他们不得不将其工作与新重置的分支重新同步。有关详细说明如何安全地还原提交而不导致硬重置而丢失工作的解决方案,请参见此答案

2
另外,要明确一点,git show HEAD等同于仅使用git log HEAD -1

25

如果情况很紧急,并且您只想以一种快速而肮脏的方式来执行发问者所要求的操作,那么您的项目就位于一个名为“我的项目”的目录下:


快速而肮脏:根据情况,快速而肮脏实际上可能非常好。我在这里的解决方案不是使用不可思议的,功能强大的git命令将工作目录中的文件不可逆地替换为从.git /目录下潜伏的git存储库的深处拖拉/提取的文件。许多。您不必进行此类深海潜水来恢复看来可能是灾难性的情况,并且在没有足够专业知识的情况下尝试这样做可能会致命


  1. 复制整个目录,然后将其命名为“ my project-copy”。假设您的git仓库(“ repo”)文件位于“我的项目”目录(默认位置,位于名为“ .git”的目录下)下,那么您现在已经复制了工作文件和repo文件。

  2. 在目录“我的项目”中执行此操作:

    .../my project $ git reset --hard [first-4-letters&numbers-of-commit's-SHA]
    

这将使“我的项目”下的存储库状态恢复为您进行提交时的状态(“提交”表示您的工作文件的快照)。此后的所有提交将永久丢失在“我的项目”下,但是... 由于您复制了所有这些文件-包括... /。git下的文件,它们仍将存在于“我的项目-复制”下的回购中。 /。

然后,您的系统上就有两个版本...您可以检查或复制或修改上一次提交中感兴趣的文件或其他内容。如果您决定新的工作,因为恢复的提交无处可走,则可以完全丢弃“我的项目-复制”下的文件。

如果您想继续进行项目状态而又不实际放弃工作,这是显而易见的事情,因为检索到的提交将再次重命名目录:删除包含检索到的提交的项目(或给它一个临时名称),然后重命名“我的项目-将“目录”复制回“我的项目”。然后也许尝试理解这里的其他一些答案,并且可能很快就会再次提交。

Git是一个绝妙的创造,但绝对没有人能够“随时随地捡起它”:尝试解释它的人也经常假设其他VCS [Version Control Systems]有先验知识,并且研究得太深了太早了,并犯下其他罪行,例如使用可互换的术语进行“结帐”-有时似乎几乎可以使初学者感到困惑。

为了减轻压力,请从我的伤疤中吸取教训。您几乎必须阅读有关Git的书-我建议您使用“使用Git进行版本控制”。尽早而不是迟些。如果这样做,请记住,Git的大部分复杂性来自分支然后进行合并:您可以跳过任何本书中的那些部分。从您的问题出发,没有任何理由使人们对科学视而不见

尤其是,例如,这是一种绝望的情况,而您是Git的新手时!

PS:另一个想法:将Git存储库保存在除具有工作文件的目录之外的其他目录中,实际上(现在)非常简单。这意味着您不必使用上述快速又肮脏的解决方案来复制整个Git存储库。在--separate-git-dir 这里查看弗莱尔的答案。但是请注意:如果您有一个不复制的“单独目录”存储库,并且进行了硬重置,则重置提交之后的所有版本将永远丢失,除非您确实拥有,定期备份您的存储库,最好备份到其他地方的云(例如Google Drive)。

关于“备份到云”这一主题,下一步是(当然是免费)在GitHub或(在我看来更好)GitLab开设一个帐户。然后,您可以定期执行git push命令以使您的云存储库“正确”更新。但是,再次谈论这个问题可能为时过早。


23

这是直接重置为最近提交的另一种方法

git stash
git stash clear

它直接清除自上一次提交以来您一直进行的所有更改。

PS:有一点问题;它还会删除您最近存储的所有存储更改。在大多数情况下,我认为这并不重要。


注意:未隐藏未添加到索引中的新文件。您也已经添加了它们或手动删除了它们。
andreyro's

为什么哦,为什么要清除藏匿处?除了解决方案外,这实际上是有害的。读取问题的第一句话会立即使隐藏解决方案无效(仅对重置为LAST commit有用)。
RomainValeri

22

为了从意外更改中彻底清除编码器的目录,我们使用了:

git add -A .
git reset --hard HEAD

Just git reset --hard HEAD将摆脱修改,但不会摆脱“新”文件。在他们的情况下,他们不小心将一个重要的文件夹随机拖到了某个地方,而所有这些文件都被Git视为新文件,因此reset --hard并没有解决。通过git add -A .预先运行,它使用git显式跟踪了它们,然后将其清除。


21

要将更改从上一次提交保留到HEAD并移至上一次提交,请执行以下操作:

git reset <SHA>

如果不需要从上一次提交到HEAD的更改,而只是放弃所有更改,请执行以下操作:

git reset --hard <SHA>


18

Revert是用于回滚提交的命令。

git revert <commit1> <commit2> 

样品:

git revert 2h3h23233

它可以像下面这样从HEAD进入范围。这里1表示“还原上一次提交”。

git revert HEAD~1..HEAD

然后做 git push


14

尝试重置为所需的提交-

git reset <COMMIT_ID>

(以检查COMMIT_ID的使用git log

这会将所有更改的文件重置为未添加状态。

现在您可以checkout通过以下方式删除所有未添加的文件

git checkout .

检查git log以确认您所做的更改。

更新

如果您只有一个并且仅在您的仓库中提交,请尝试

git update-ref -d HEAD


13

当您的提交被远程推送时,您需要将其删除。让我假设您的分支正在发展,并且已经超过原点

您首先需要从源中删除开发

git push origin :develop (note the colon)

然后,您需要发展到所需的状态,让我假设提交哈希为EFGHIJK:

git reset --hard EFGHIJK

最后,再次推动开发

git push origin develop

13

警告!如果用户错误地输入了错误的提交,该命令可能会导致丢失提交历史。始终在其他地方进行git的额外备份,以防万一您犯错,那会比安全一些。:)

我遇到过类似的问题,想恢复到以前的提交。就我而言,我不希望保留较新的提交,因此我使用Hard

这是我的方法:

git reset --hard CommitId && git clean -f

这将在本地存储库上还原,并且在使用git push -f后将在此处更新远程存储库。

git push -f

13

GitKraken中,您可以执行以下操作:

  1. 右键单击要重置的提交,选择:重置为此提交/硬

    在此处输入图片说明

  2. 再次右键单击提交,选择:当前分支名称/推送

    在此处输入图片说明

  3. 单击强制推送

    在此处输入图片说明

观察 :您需要小心,因为所有在硬重置后的提交历史都将丢失,并且此操作是不可逆的。您需要确定自己在做什么。


11

如果要在最后一次提交中更正某些错误,可以使用git commit --amend命令来替代。如果没有任何引用指向最后一次提交,则将成功,因为它将创建一个与最后一次提交具有相同父级的提交。如果没有对最后一次提交的引用,它将被简单地丢弃,并且该提交将成为最后一次提交。这是纠正提交而不恢复提交的好方法。但是它有其自身的局限性。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.