7620

如何从当前状态恢复到某个提交时的快照?

如果我这样做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

4

41 回答 41

11269

这在很大程度上取决于您所说的“还原”是什么意思。

暂时切换到不同的提交

如果你想暂时回到它,鬼混,然后回到你所在的地方,你所要做的就是检查所需的提交:

# 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,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 (non inclusive of first hash):
git revert 0d1d7fc..a867b4a

# 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 移回以前的位置?(分离的头)和撤消提交

于 2010-11-06T17:04:54.543 回答
2841

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

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

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

(该--no-commit标志允许 git 一次恢复所有提交 - 否则将提示您为范围内的每个提交提供一条消息,从而在您的历史记录中添加不必要的新提交。)

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

于 2014-02-12T04:18:01.250 回答
1813

流氓编码器?

自己工作,只想让它工作?请遵循以下这些说明,它们多年来一直为我和许多其他人可靠地工作。

与他人合作?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

归功于类似的 Stack Overflow 问题,Revert to a commit by a SHA hash in Git? .

于 2012-08-21T06:19:52.847 回答
270

对我和其他人来说最好的选择是 Git 重置选项:

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

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


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

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

git clean -i
于 2013-10-22T11:53:42.647 回答
252

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

首先什么是HEAD?

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

的内容HEAD存储在.git/HEAD中,它包含当前提交的 40 字节 SHA-1 哈希。


detached HEAD

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

说明分离 HEAD 概念的图表

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

在终端中运行 git checkout HEAD^0


关于如何从分离的 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 reflog


git reset HEAD --hard <commit_id>

“移动”你的HEAD背部到所需的提交。

# 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.

这个模式说明了哪个命令做什么。如您所见,reset && checkout修改HEAD.

说明暂存区和检查 HEAD 的图表

于 2015-02-05T21:56:02.153 回答
188

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

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

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

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

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

然后它将保存您的更改。

于 2014-12-12T06:52:36.460 回答
180

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

git reset --soft HEAD~1
  • --soft表示应将未提交的文件保留为工作文件,否则--hard将丢弃它们。
  • HEAD~1是最后一次提交。如果你想回滚 3 个提交,你可以使用HEAD~3. 如果您想回滚到特定的修订号,您也可以使用其 SHA 哈希来执行此操作。

在您提交了错误的事情并且想要撤消最后一次提交的情况下,这是一个非常有用的命令。

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

于 2014-03-04T17:25:52.093 回答
126

最好的方法是:

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

这会将分支重置为特定的提交,然后将使用与本地相同的提交上传远程服务器。

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

于 2020-02-25T17:00:01.137 回答
118

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

git add . && git checkout master -f

简短的介绍:

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

我找到了一种更方便和简单的方法来实现上述结果:

git add . && git reset --hard HEAD

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

它与 boulder_ruby 建议的代码代码相同,但我git add .之前 添加git reset --hard HEAD了删除自上次提交以来创建的所有新文件,因为这是大多数人在恢复到最新提交时所期望的。

于 2012-07-29T11:01:03.643 回答
102

好的,回到 Git 中的先前提交非常容易......

在不保留更改的情况下恢复:

git reset --hard <commit>

恢复并保留更改:

git reset --soft <commit>

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

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


- 柔软的

解释的默认标志,不需要提供它,不会更改工作树,但它会添加所有已更改的文件准备提交,因此您返回到提交状态,对文件的更改将取消暂存。


- 难的

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


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

Git 重置为提交

于 2017-07-20T15:55:53.507 回答
80

假设您正在谈论 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 的一个重要原因。

最好使用revert(见其他答案)而不是reset。如果你是一个人的团队,那么这可能并不重要。

于 2016-05-10T17:21:43.087 回答
66

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 old commit 的解决方案并使其成为新提交

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

与备选方案#1 类似,这再现了<commit>当前工作副本中的状态。有必要先做,git rm因为git checkout不会删除自<commit>.

于 2014-06-29T17:51:16.937 回答
65

~/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 没有 agit revert --to <hash>超出了我的范围。

于 2011-10-13T21:51:36.150 回答
61

这是一种更简单的方法可以返回到先前的提交(并使其处于未提交状态,随心所欲地处理它):

git reset HEAD~1

所以,不需要提交 ID 等等:)

于 2016-02-29T08:40:30.403 回答
53

您可以自己完成所有这些初始步骤并推送回 Git 存储库。

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

  2. -n 4从终端运行 Git log 命令。后面的数字-n决定了从本地历史中最近一次提交开始的日志中的提交次数。

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

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

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

git pull --all
git reset --hard HEAD~1
git push --force
于 2017-04-06T12:20:25.253 回答
51

警告!如果用户错误地提交了错误的提交,此命令可能会导致丢失提交历史。总是在其他地方对你的 git 进行额外的备份,以防万一你犯了错误,这比你更安全一些。:)

我遇到了类似的问题,想恢复到之前的提交。就我而言,我对保留较新的提交不感兴趣,因此我使用了Hard.

我是这样做的:

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

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

git push -f

例如,如果你想完全忽略enforce non-group manage policies下一张图片中名称的提交

在此处输入图像描述

你会跑

git reset --hard dd52eb9 && git clean -f

其次是

git push -f

之后,您将不会在那里看到该提交 ( enforce non-group manage policies)

在此处输入图像描述

于 2018-01-08T14:15:56.717 回答
41

在所有更改之后,当您推送所有这些命令时,您可能必须使用:

git push -f ...

而且不仅如此git push

于 2013-09-05T14:03:19.297 回答
39

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

git back

根据手册页,它也可以这样使用:

# Remove the latest three commits
git back 3
于 2013-08-08T18:30:12.267 回答
32

尝试重置为所需的提交:

git reset <COMMIT_ID>

检查COMMIT_ID使用:

git log

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

现在您可以checkout通过

git checkout .

要验证您的更改,请使用:

git log

更新

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

git update-ref -d HEAD
于 2017-05-06T23:03:03.577 回答
31

选择您需要的提交,并通过

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

直到您获得所需的提交。要使 HEAD 指向这一点,请执行

git reset --hard HEAD~1

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

于 2014-02-26T12:52:41.107 回答
31

Revert 是回滚提交的命令。

git revert <commit1> <commit2> 

样本:

git revert 2h3h23233

它能够从 HEAD 获取范围,如下所示。这里 1 表示“恢复上次提交”。

git revert HEAD~1..HEAD

然后做:

git push
于 2015-08-20T14:45:11.710 回答
30

如果情况很紧急,并且您只想以一种快速而肮脏的方式做提问者所问的事情,假设您的项目位于名为“我的项目”的目录下:


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


  1. 复制整个目录并将其命名为其他名称,例如“我的项目 - 复制”。假设您的 git 存储库(“repo”)文件位于“my project”目录下(它们的默认位置,位于名为“.git”的目录下),您现在将复制您的工作文件和 repo 文件。

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

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

这会将“我的项目”下的存储库状态返回到您提交时的状态(“提交”表示您的工作文件的快照)。自“ resetted”提交以来的所有提交将在“我的项目”下永远丢失,但是......它们仍将出现在“我的项目 - 副本”下的存储库中,因为您复制了所有这些文件 - 包括存储库中的文件,在 .../.git/ 下。

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

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

Git 是一个绝妙的创造,但绝对没有人能够“即时掌握”:试图解释它的人也经常假设其他 VCS [版本控制系统] 的先验知识并深入研究太远太早了,并犯下其他可怕的罪行,例如使用可互换的术语来表示“结帐”-有时看起来几乎是故意使初学者感到困惑的方式。

为了减轻自己的压力,请从我的伤疤中学习。你几乎必须阅读一本关于 Git 的书——我建议阅读 THE BOOK, Pro Git 2nd edition :可从 git central免费下载等。2014 年出版,但截至 2022 年初,仍然是最好的。尽早行动:从现在开始,Git 注定要成为你生活的一部分。如果你这样做了,请记住 Git 的大部分复杂性来自分支然后重新合并:Pro Git书实际上非常温和地介绍了这个核心方面,但你可以在第一次阅读任何书中跳过这些部分。从你的问题来看,人们没有理由用科学来蒙蔽你

尤其是如果,例如,这是一个绝望的情况,而你是 Git 的新手!

PS:(稍微谨慎)另一个想法:(现在)将 Git 存储库保存在与工作文件不同的目录中实际上非常简单。这意味着您不会使用上述快速而肮脏的解决方案复制整个 Git 存储库。请参阅 Fryer 使用--separate-git-dir 此处的答案。牢记这一点,请注意:如果您有一个未复制的“单独目录”存储库,并且您进行了硬重置,那么重置提交之后的所有版本都将永远永远丢失,除非您有,正如您绝对应该的那样,定期备份您的存储库,最好备份到云端(例如Google Drive)等其他地方。

关于“备份到云端”这个主题,下一步是在 GitHub 或(在我看来更好)GitLab开设一个帐户(当然免费) 。然后,您可以定期执行git push命令以“正确”更新您的云存储库。但同样,谈论这个可能为时过早:git push必须进行配置,可能由于完全令人费解的技术原因而无法工作,涉及了解远程存储库(“来源”等)。因此,在您变得知识渊博之前,一种快速而简单的基于云的备份方法可能更可取。再次,Pro Git书介绍了远程存储库的工作方式,以及与您的本地存储库的关系,非常温和和合理。

于 2015-03-19T17:33:31.133 回答
30

恢复到最近的提交并忽略所有本地更改:

git reset --hard HEAD
于 2016-07-26T13:13:55.780 回答
23

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

git stash
git stash clear

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

PS:有点小问题;它还会删除您最近存储的所有存储更改。我想在大多数情况下这无关紧要。

于 2016-05-05T11:43:08.367 回答
22

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

git add -A .
git reset --hard HEAD

只是git reset --hard HEAD会摆脱修改,但不会摆脱“新”文件。在他们的情况下,他们不小心将一个重要文件夹随机拖到某个地方,并且所有这些文件都被 Git 视为新文件,因此 areset --hard没有修复它。通过git add -A .预先运行,它使用 git 明确地跟踪它们,并被重置清除。

于 2015-10-11T00:10:36.880 回答
21

我相信有些人可能会遇到这个问题,想知道如何回滚他们在 master 中所做的已提交更改 - 即扔掉所有东西并返回到 origin/master,在这种情况下,请执行以下操作:

git reset --hard origin/master

https://superuser.com/questions/273172/how-to-reset-master-to-origin-master

于 2015-02-05T01:28:42.440 回答
21

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

git reset <SHA>

如果从上一次提交到 HEAD 不需要更改并丢弃所有更改,请执行以下操作:

git reset --hard <SHA>
于 2015-07-28T08:35:40.137 回答
21

想法:您基本上想用先前提交的状态替换当前的工作树状态,然后从中创建一个提交。忽略的文件最好不要更改。方法如下:

  1. 清空工作树 *.

     git rm -r --cached . && git clean -f -d
    
  2. 将工作树置于我们想要的状态**。

     git checkout 0d1d7fc3 .
    
  3. 创建还原提交。

     git add --all && git commit -m "revert to 0d1d7fc3"
    

起初我认为Yarins 的答案是最好的,但它不适用于合并提交。这个解决方案可以。

此外,它不会从历史记录中删除任何内容(推送或推送)。它产生一个干净的提交,代表我们想要恢复的状态。


* 通过从工作树中删除未跟踪但未被忽略的文件(在.gitignore中指定的文件)。工作树是空的,除了我们想要保留的被忽略的文件(如果没有-x为 指定选项clean

** 当指定路径时(此处:.),结帐将单独留下 HEAD。

于 2019-11-10T10:10:02.463 回答
14

当您的提交被远程推送时,您需要删除它们。让我假设您的分支是develop并且它被推过origin

您首先需要从origin中删除develop

git push origin :develop (note the colon)

然后你需要开发到你想要的状态,让我假设提交哈希是 EFGHIJK:

git reset --hard EFGHIJK

最后,再次推动开发

git push origin develop
于 2017-03-20T07:33:12.510 回答
13

对于回滚(或还原):

1. git revert --no-commit "commit-code-to-remove" HEAD
(e.g. git revert --no-commit d57a39d HEAD)
2. git commit
3. git push

尝试以上两个步骤,如果你发现这是你想要的,那么git push

如果您发现有问题,请执行以下操作:

git revert --abort
于 2016-11-01T14:29:37.773 回答
12

如果您想纠正上次提交中的一些错误,一个不错的选择是使用git commit --amend命令。如果最后一次提交没有被任何引用指向,这将起到作用,因为它创建了一个与最后一次提交具有相同父级的提交。如果没有对最后一次提交的引用,它将被简单地丢弃,这个提交将是最后一次提交。这是在不恢复提交的情况下更正提交的好方法。但是,它有其自身的局限性。

于 2015-07-01T11:35:54.610 回答
12

GitKraken 中,您可以这样做:

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

    在此处输入图像描述

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

    在此处输入图像描述

  3. 单击强制推送

    在此处输入图像描述

观察。: 你需要小心,因为硬重置后的所有提交历史都丢失了,这个动作是不可逆的。你需要确定你在做什么。

于 2018-05-02T18:41:36.523 回答
11

首先,获取标识某个日期提交的字符串,执行以下操作:

git rev-list -n 1 --before="2009-07-27 13:37" origin/master

它打印提交标识符,获取字符串(例如 XXXX)并执行以下操作:

git checkout XXXX
于 2017-05-05T14:39:47.420 回答
9

另一个最简单的解决方案;您必须更改分支才能执行此操作,但之后您可以运行:

git branch -f <<branchname>> 0d1d7fc32e5a947fbd92ee598033d85bfc445a50
于 2015-12-04T15:27:52.573 回答
9

使用Sourcetree可以更轻松地完成它。只需右键单击您要查找的提交并从菜单中选择“结帐”。

在此处输入图像描述

于 2017-05-26T11:18:48.720 回答
8

由于某种原因,我无法手动恢复我的,所以这就是我最终的做法。

  1. 检查了我想要的分支,复制它。
  2. 查看了最新的分支。
  3. 将我想要的分支的内容复制到最新分支的目录,覆盖更改并提交。
于 2015-02-23T17:20:33.807 回答
8
git reflog

选择 git reflog 的 HEAD(s) 的数量,您想要恢复并执行(对于这个例子,我选择 12):

git reset HEAD@{12} --hard
于 2016-09-28T02:53:26.287 回答
7

我发现将分支恢复到任何特定提交的最简单的方法是:

  1. 查看您希望从中恢复的提交或分支。
  2. 编辑 .git/HEAD 并将 ref 更改为您要恢复到的分支。

如:

echo 'ref: refs/heads/example' > .git/HEAD

如果你这样做git status了,你应该看到你所在的分支和你想要恢复的分支之间的所有变化。

如果一切看起来都不错,您可以提交。您还可以使用git diff revert..example 来确保它是相同的。

于 2017-12-07T16:01:40.300 回答
7

如果您想暂时还原更改,因为

  • 某人提交的代码破坏了构建或破坏了您正在处理的功能

您可以使用搜索最后一个工作提交git log,然后运行:

git rebase --onto <commitId>

当远程分支再次工作时,您可以

git pull --rebase

这种方法比git checkout临时更改要好,因为您没有处于分离状态。

于 2017-11-10T20:07:36.730 回答
6

重置分阶段的更改和提交

git reset命令允许您更改存储库的 HEAD(工作树指向的最新提交)。它修改暂存区或暂存区和工作树。

Git 能够完全按照您的意愿制作提交,这意味着您有时需要撤消对您使用git add. 你可以通过调用来做到这一点git reset HEAD <file to change>

您有两种选择可以完全摆脱更改。git checkout HEAD <file(s) or path(s)>是一种快速撤消对暂存区和工作树所做更改的方法。但是,请小心使用此命令,因为它会删除对工作树的所有更改。

Git 不知道这些更改,因为它们从未被提交。运行此命令后,无法恢复这些更改。

您可以使用的另一个命令是git reset --hard. 它对您的工作树同样具有破坏性 - 任何未提交的更改或分阶段的更改在运行后都会丢失。运行git reset -hardHEAD 与git checkout HEAD. 它只是不需要文件或路径即可工作。

您可以--soft使用git reset. 它将存储库重置为您指定的提交并暂存所有这些更改。您已经暂存的任何更改都不会受到影响,工作树中的更改也不会受到影响。

最后,您可以使用它--mixed 来重置工作树,而无需暂存任何更改。这也会取消暂存的任何更改。

恢复提交

有时我们会犯错误。不应该共享的提交被推送到公共存储库,提交有一个无法修复且需要撤消的错误,或者您可能不再需要该代码。

这些案例都需要git revert。该git revert命令正是您所期望的。它通过对历史应用反向提交来恢复单个提交。

有时您需要还原多个提交才能完全撤消更改。您可以使用-no-commit,也可以使用-n告诉 Git 执行还原,但不要提交更改。

这使您可以将所有恢复提交合并到一个提交中,如果您需要恢复跨越多个提交的功能,这很有用。确保以相反的顺序恢复提​​交 - 首先是最新的提交。

否则,您可能会因为尝试还原尚不存在的代码而混淆 Git。

于 2019-01-29T10:01:16.380 回答
1

有许多答案提供删除最后一次提交。但是,这里询问如何删除特定的提交,在这种情况下是删除最后三个提交,回到 11 月 3 日的提交。

你可以用变基来做到这一点。只需这样做:

git rebase -i HEAD~4

这将列出您的最后四个提交。

现在您可以选择删除提交。你用drop文本来做。

  • 只需点击i你的键盘,然后在你想要删除 writedrop而不是 default的提交旁边pick

  • 在键盘上,点击exit:wq

要确保删除提交,请编写:

git log

您将看到您保存为 drop 的提交已被删除。

要将这些更改推送到您的远程分支,请编写:

git push --force
于 2020-01-07T00:35:03.403 回答