如何在GitHub上删除提交?

2023

我“无意中”将一个提交推送到了GitHub上。

有没有可能删除这个提交?

我想要将我的GitHub仓库还原为在这个提交之前的状态。


224
警告:如果你有很多人关注你的代码仓库,千万不要这样做,否则会导致他们本地的代码仓库与最新版本不同步。如果这是一个错误,你可以再提交一次撤销错误。如果这涉及密码,你可能需要更改密码,而不要着急删除它。强制性操作并非没有缺点。 - Tamara Wijsman
177
注意事项2:通过SHA1,提交仍然可以直接访问。强制推送并不会删除提交,它只是创建一个新的提交并将文件指针移动到该提交。要真正删除提交,您必须删除整个存储库。 - Gustav
31
“...你必须删除整个代码库。” - 或者只需强制进行垃圾回收即可。 - IQAndreas
6
关于WOC1,下一次关注者拉取时,他们将自动获取新的历史记录并失去旧的记录,这似乎是相当可接受的行为。问题是,如果其他人在您提交之后进行了新的工作:那么您会给他们带来很大的麻烦(他们需要将更改挑选到新的历史记录上)。因此,在* 1分钟 之后进行强制推送比在 1周 之后更容易被接受(暴露给较少的关注者),对于人们仅使用而不修改*的项目也更容易被接受(他们不会注意到时间轴已更改)。 - joeytwiddle
11
这是一个关于在Bitbucket上删除最后一次提交的问题。 - naught101
显示剩余9条评论
21个回答

1473

注意:请参见下面的评论中对git rebase -i的替代方法—

git reset --soft HEAD^

首先,在您的本地代码库中删除提交。您可以使用git rebase -i命令来完成此操作。例如,如果它是您最后一次提交,您可以运行 git rebase -i HEAD~2 命令,并在弹出的编辑器窗口中删除第二行。

然后,通过使用 git push origin +branchName --force 命令来强制推送到GitHub。

有关更多信息(例如,如果您要删除旧提交),请参见Git Magic 第5章:历史课程-还有一些

哦,如果您的工作树处于脏状态,则必须首先执行git stash命令,然后再执行git stash apply命令。


30
请注意,这仍将在引用日志中保留提交记录。如果您在其中有敏感数据,则可能需要完全删除存储库。 - troelskn
137
我感到困惑。为什么使用 git reset --soft HEAD^ 然后执行 git push origin +master 不能撤消提交?为什么在这种情况下我们要使用 git rebase -i HEAD^^ - Dennis
63
因为我在3.5年前不熟悉"reset --soft"命令。=) - Can Berk Güder
3
@Nick 完成了。我刚刚使用了 git reset --soft 方法,效果非常好。git rebase 是一种让我感到害怕的 git 黑魔法。 - noahlz
46
大家注意了。请看下面 subutux 的评论。即使强制将代码提交推送至 GitHub 后, GitHub 仍会缓存您的提交内容。请参考 https://help.github.com/articles/remove-sensitive-data : “注意:一旦提交已推送,你应该认为数据已经泄露。如果你提交了密码,请更改它!如果你提交了密钥,请生成一个新的。” - Patrick
显示剩余14条评论

1112
git push -f origin HEAD^:master

那应该“撤消”推送。


39
这也行!它删除了GitHub上的推送,但保留了我的本地存储库。谢谢! - hectorsq
13
好的,是的。它只会执行你所要求的操作。 :) 你的代码仓库和远程仓库并不需要拥有匹配的引用。 - Dustin
42
注意,这只是移动了分支指针。误推的提交仍然存在于远程仓库中。在GitHub的情况下,这意味着如果你知道SHA-1哈希值(例如从用户活动历史记录中),它仍然可以被看到。 - Thiago Arrais
90
执行以下命令:git push -f origin HEAD^^:master,可以撤销最近的两次更改,将其中的代码推回到远程仓库。如果需要撤销更多次的更改,则可以将命令中的“^^”替换为“~n”,其中n是需要撤销的更改次数。 - ianj
28
请注意,带有n个^的HEAD可以被HEADn替换,例如,HEAD^^^可以替换为HEAD3。 - Mark Reed
显示剩余12条评论

521

为了方便回退,这里提供另一种可能性(自该提交以来的所有内容将被删除):

git reset --hard commit_hash_you_want_to_return_to
例如,如果您想将分支重置为过去的提交,如71c27777543ccfcb0376dcdd8f6777df055ef479
git reset --hard 71c27777543ccfcb0376dcdd8f6777df055ef479
下一步是将您的分支修改推送到 origin(远程仓库):
git push --force

注意

请记住,如果其他贡献者正在使用您的分支进行工作,他们可能会遇到冲突或其他问题,因为您正在更改该分支的历史记录,但仅适用于您自己,而不适用于那些已经使用您的分支的人。请注意。


16
警告:这将重写你的历史记录,你将失去提交并且通常在协作环境中不是一个很好的做法。 - Oliver
11
是的,这对我来说是最简单且最好的选择。在我提交其他内容的PR之前,我的dev分支需要被还原。我本应该一开始就把我的更改放在一个分支上。 - Web and Flow
1
这适用于未受保护的分支。如果Github分支受到保护,强制推送将失败。 - Adarsha
运行得非常好。尽管个人资料页面仍然显示提交已推送到存储库。 - Prateek Gulati
这样做也会从Github上的远程仓库中删除所有痕迹吗? - timman
显示剩余6条评论

148
  1. 使用git log查找你要还原的提交记录

  2. 在执行git push origin +7f6d03:master命令时,将7f6d03替换为错误提交之前的提交记录。+表示使用force push

就是这样了。

这里有一个非常好的指南来解决您的问题,简单易懂!


1
这对我来说很有效,可以从分支中删除最近发布的几个提交。 - High Performance Rangsiman
2
在经过一段时间的尝试后,你明确指出要插入最后一个期望的提交,这样我才明白为什么这个命令没有起作用。而我一直在尝试进行第一次提交,这就是为什么我收到了“已经是最新的”的消息。 - Luis Febro
1
这应该是被接受的答案,因为问题没有指明要删除哪个提交。被接受的答案只删除最后一个提交。而这个答案则可以删除任何提交。 - Dominic Cerisano
这会从远程仓库中删除它吗? - timman

105

如果您希望在删除后保留提交更改:

请注意,此解决方案仅适用于要删除的提交是最后提交的情况。


1 - 从日志中复制要返回的提交引用:

git log

2-将git重置到提交参考:

 git reset <commit_ref>

3 - 将本地错误提交的更改存储起来,以便稍后推送到远程:

 git stash

4 - 推送变更到远程仓库,(-f或--force):

git push -f

5 - 将存储的更改取回到本地代码库:

git stash apply

7 - 如果你在更改中有未跟踪/新的文件,则需要在提交之前将它们添加到Git:

git add .

6- 添加您需要的任何额外更改,然后提交所需的文件(或者使用点“.”而不是列出每个文件名来提交本地仓库中的所有文件):

git commit -m "<new_commit_message>" <file1> <file2> ...
或者
git commit -m "<new_commit_message>" .

1
谢谢!我很高兴把它恢复到5。然后我就可以在 Github 桌面上进行更改了。 - user2568374

48
git reset HEAD^ --hard
git push origin -f

这对我起作用。


当已经将提交推送到GitHub时,会显示“一切都是最新的”。 - Benny Code
如果提交 A 是最新的,B 是第二个。你想重置哪个提交? - Hilen
A是最新的版本,我想回到B。 - Benny Code
1
git reset B --hard then git push origin -f - Hilen
当我想要从我正在使用的分支中删除提交时,这对我效果最佳。 - LeraA

47

12
即使你从分支中删除了提交,如果你知道URL/SHA-1,该提交仍然可以在GitHub上找到。唯一从缓存中删除提交的方法是联系GitHub支持(请参阅该链接中的“Github上的缓存数据”部分)。 - Patrick
5
我想指出,实际上解释页面上的内容并引用相关部分可能是更好的主意。在帮助指南中提到:“鼓励使用外部资源的链接,但请在链接周围添加上下文,以便您的用户了解它是什么以及为什么存在。始终引用重要链接的最相关部分,以防目标网站无法访问或永久离线。” 经验法则:假装链接不存在,或者他们无法点击它。 - Jeremy Rodi
3
清除缓存还有另外一种方法:删除仓库,然后重新创建并推送。虽然这对于每个人来说可能都不可行,但对于许多人来说,这比联系 Github 支持更容易、更快速(也许您不想指向一个第三方 [Github],而且您推送了敏感数据)。 - Juliane Holzt

43

删除最近的提交,但保留您所做的工作:

git reset --soft HEAD~1

删除最近的提交,摧毁你所做的工作:

git reset --hard HEAD~1

12
之后的推动怎么样? - user2568374

28

使用git revert撤销您的推送。

git-revert - 撤销一些已经存在的提交

git revert [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>...
git revert --continue
git revert --quit
git revert --abort
撤销相关补丁引入的更改,记录一些新提交以记录它们。这需要您的工作树是干净的 (没有来自 HEAD 提交的修改)。
注意:git revert 用于记录一些新的提交以撤销一些先前的提交的影响 (通常只是一个错误的提交)。如果您想要放弃工作目录中所有未提交的更改,您应该查看 git reset,特别是 --hard 选项。

14
这是避免破坏他人代码库的推荐方式。它创建一个新的提交,用来撤销之前的提交。但这并没有回答问题,即如何从“历史记录”中删除一个提交。 - joeytwiddle
许多其他答案都很好,但如果您无法对主分支进行强制推送,则似乎只有这种方法可行。 - Christopher Hunter
请将以下与编程有关的内容从英语翻译成中文。只返回翻译后的文本:示例用法将有所帮助,比粘贴man页要好。帮助人们理解[]相关的内容。 - pauljohn32

25

从远程仓库中删除提交记录:

 git push -f origin last_known_good_commit:branch_name

为了从您的本地代码库中删除提交:

git reset --hard HEAD~1

链接


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