撤销 git pull,如何将存储库恢复到旧状态

1432

有没有办法撤销 git pull,使我的源代码库恢复到 git pull 前的状态? 我想这么做是因为它合并了一些我不想合并的文件,但仅合并其他剩余文件。所以,我想取回那些文件,这可行吗?

编辑:为澄清起见,我想撤消 git 合并。

git reflog
bb3139b... HEAD@{0}: pull : Fast forward
01b34fa... HEAD@{1}: clone: from ...name...

现在,我该怎么办?执行git reset --hard可以吗?我不想再搞砸了,所以想要详细的步骤。


36
你的历史记录中好像只有两个操作:克隆和拉取。直接重置到克隆状态,使用命令 git reset --hard 01b34fa。在这种情况下,你也可以使用命令 git reset --hard HEAD^,将代码重置到当前版本的前一个提交。 - jkp
3
如果你想修改工作目录中的文件,就需要使用--hard参数。 - William Pursell
3
如果它有效,您始终可以接受答案;) - jkp
12
撤销所有本地代码改动并回退到上一个提交状态。翻译: git reset --hard HEAD^ - funroll
8
git reflog会显示Git上所有的操作记录。关于使用 git reset --hard [reflog中某次操作的SHA1值] 命令的一个担忧是,有时候我们不希望回退所有在 reflog 中显示的操作,例如你想要撤销一个从远程库拉下来的、包含错误数据的主分支上的合并(这种情况经常发生),而在那次合并之后你又在其他分支上工作了。reflog 会显示其他分支上的所有更改记录。但是,只执行 git checkout mastergit reset --hard [合并前主分支上某个提交的SHA1值] 命令,将仅重置当前主分支,移除从远程库拉下来的合并记录。 - Vladimir Vukanac
显示剩余2条评论
19个回答

2043

运行git pull会按照以下顺序执行以下任务:

  1. git fetch
  2. git merge

合并步骤将合并到您的配置中设置为要合并的分支。 您想撤消合并步骤,但可能不想撤消获取(这没有太多意义,也不应该是必要的)。

要撤消合并,请使用git reset --hard将本地存储库重置为先前状态;使用git-reflog查找先前状态的SHA-1,然后将其重置。

警告

此部分列出的命令将删除所有未提交的更改,可能导致工作丢失:

git reset --hard

或者,将其重置到特定时间点,例如:

git reset --hard master@{"10 minutes ago"}

381
选取之前的状态时,可以使用master@{1}这样的快捷方式,而不是使用git-reflog并复制哈希值。master@{1}表示master的上一次位置,master@{"5 minutes ago"}master@{14:30}等等也可以使用。有关如何以此方式指定版本的详细信息,请参阅man git-rev-parse中的“specifying revisions”部分。 - Cascabel
43
在这种情况下,ORIG_HEAD 也应该起作用("git reset --hard ORIG_HEAD")。 - Jakub Narębski
1
当我拉取时,它会显示“正在更新d2c90a3..035ac4d”。在这里,您也可以使用“d2c90a3”作为参数进行重置。 - Thai
5
警告:git reset --hard master@{"10 minutes ago"} 使我的仓库回到了第一个提交,我失去了所有内容。 - brugobi
1
警告:git reset --hard master@{"10分钟前"} 几乎删除了我所有的 git 历史记录。 - JMess
显示剩余5条评论

525

与jkp的回答相同,但这里是完整的命令:

git reset --hard a0d3fe6

a0d3fe6是通过执行以下步骤找到的:

git reflog

并查看您想要撤销的点。


2
为什么我不能只做 git reset HEAD --hard 呢? - mc9
11
这种方法允许您返回多个版本之前的提交,例如。 - xji
4
我无法使用左侧的 ID,但是 git reset --hard HEAD@{n} 可以使用。 - E. Sundin
2
你应该在这么多年后,建议修改jkp的答案,而不是几乎复制它到这里。 - Abhishek Anand
  • git reflog, 然后检查HEAD,
  • git reset --hard HEAD@{11} 这对我有用。
- Pradeep B P
显示剩余2条评论

207

撤销合并的一种更现代的方法是:

git merge --abort

还有一种稍微老一点的方法:

git reset --merge

之前回答中描述的老式方法(警告:将丢弃您所有的本地更改):

git reset --hard

实际上,需要注意的是 git merge --abort 只在 MERGE_HEAD 存在时等价于 git reset --merge。这可以在 git help merge 命令中找到。

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

在合并失败且没有MERGE_HEAD时,可以使用git reset --merge撤销失败的合并,但不一定能使用git merge --abort,因此它们不仅仅是相同事物的新旧语法。这就是为什么我认为git reset --merge在日常工作中更加实用。


33
git merge --abort 只在合并过程中起作用,而不是在 git pull 完成后。因此,这个回答似乎与问题无关。 - Abhishek Anand
3
git reset --merge会删除所有未被提交的更改。我通过一次艰难的经历得知了这一点。 - theadriangreen
致命错误:没有要中止的合并(缺少MERGE_HEAD) 即使在(不成功的)合并期间也无法工作 - Bersan
2
这正是我所需要的,因为我还没有完成全部拉取。我知道这与此无关,但在我的搜索中仍然很有帮助。 - jAC

90

它有效了 首次使用:git reflog

找到你先前状态的SHA并使其还原(HEAD@{1}是一个示例)

git reset --hard HEAD@{1}

当您刚刚完成拉取操作但出现错误并需要快速回滚时,您需要的实际一行代码。 - Daniel Howard

59
假设$COMMIT是您执行git pull之前的最后一个提交ID。 您需要撤消上一次拉取的最后一步操作是

git reset --hard $COMMIT

。 奖励: 在谈到拉取时,我想分享一个有趣的技巧,

git pull --rebase

。 这个命令是我 git 生活中最有用的命令,它节省了大量时间。 在将新提交推送到服务器之前,请尝试此命令,并且它会自动同步最新的服务器更改(使用fetch + merge),并将您的提交放在 git 日志的顶部。 不必担心手动拉取/合并。 在http://gitolite.com/git-pull--rebase找到详细信息。

44
如果您已经安装了gitk(尝试从git命令行运行“gitk --all”),那么很简单。只需运行它,选择要回滚到的提交(右键单击),然后选择“将主分支重置为此处”。如果没有未提交的更改,则选择“hard”选项。

10
如果你还没看过它,这值得一试。它会弹出一个疯狂的图形用户界面。 - Evan Moran

28

这是撤销您的拉取更改最简单的方法。

** Warning **
请备份您所更改的文件,因为此操作将会删除新创建的文件和文件夹。
git reset --hard 9573e3e0

其中 9573e3e0 是你的 {Commit id}


这个回复非常有用,因为如果我们执行 git pull origin branch 命令,会得到类似于 Updating ffce65bd..e929e884 的输出,然后可以执行 git reset --hard ffce65bd 命令。 - Ernesto Alfonso

21

你可以运行git reset --hard ORIG_HEAD

因为"pull"或"merge"将ORIG_HEAD设置为执行这些操作前的当前状态。


17

查看您执行 git pull 命令的 当前分支 中的日志记录

git log

样本输出将看起来像这样

commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxa3dd0
Author: user <user@gmail.com>
Date:   Tue Nov 23 20:19:58 2021 +0530

    latest changes

commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxd697b
Author: user <user@gmail.com>
Date:   Tue Nov 23 17:45:44 2021 +0530

    latest changes includes account details api

commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxc0e6fa
Author: user <user@gmail.com>
Date:   Tue Nov 23 17:02:39 2021 +0530

    latest changes

复制你想要的最后提交ID。例如,如果您的最后提交ID为xxxxxxxxxxxxxxxxxxxxxxxxxxxxxc0e6fa(假设此提交ID是在您执行git pull之前的最后提交ID),并且在此提交ID之上两次提交是在您执行git pull命令之后进行的,则使用此提交ID获取以前的更改。

git reset --hard xxxxxxxxxxxxxxxxxxxxxxxxxxxxxc0e6fa

执行此操作将删除此提交ID上方的提交。在此之后,您将获得先前的更改,就是这么简单。


17

要将最近一次合并撤销到您的custom-branch,最简单的方法是:

git reset --hard custom-branch@{1}

主分支示例:

git reset --hard main@{1}

这个方法非常好用,可以撤销别人做的混乱变基。我已经拉取了它,并且通过这个方法成功地撤销了那次拉取,恢复了我的旧本地分支。 谢谢。 - MumiaIrrequieta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接