我该如何从一个分支中删除一个提交?

4268

我该如何从我的分支历史记录中删除一个提交?我应该使用 git reset --hard HEAD 吗?


67
我认为这篇文章不是Git undo last commit相同,因为它询问如何从一个分支中删除任何提交。我还认为没有一个答案实际回答了这个问题。它们都是倒退到最后提交的状态,而不是cherry-pickdelete一次性提交,即使这个提交发生在很久以前。 - Chris
23
@Chris,答案“git rebase -i HEAD~10”确实回答了问题,因为它允许您任意选择要删除的提交。Git会逐个应用您指定范围内的提交,忽略您从日志中删除的提交。我今天使用这个命令来摆脱我的存储库中第二和第三个最近的提交,同时保留顶部的提交。我同意其他答案都不令人满意。 - MST
@MST 是的,我应该说,接受的答案中没有任何选项解决了这个问题,但你是完全正确的 - 那个命令似乎有效。 - Chris
3
我认为 git reset --soft HEAD~1 正是你所需要的。 在这种情况下,你将撤销提交并保存你的工作。reset --hard 将完全删除提交。 - sergpank
幸运的是,我可以只写一个空提交信息,这样提交就不会被提交了:),所以我不需要删除它。简而言之:我偶然运行了命令git commit -a,认为它是git commit --amend的缩写(实际上不是),并且在一个新的空提交消息中。我可以使用空消息取消编辑器(在vim中使用:wq),git不会创建提交,而是返回“由于空提交消息而中止提交。” - questionto42
显示剩余2条评论
38个回答

57
git reset --hard commitId

git push <origin> <branch> --force

PS:CommitId是指您想还原回去的那一个。


git push --force <origin> <branchName>。如果不指定分支名称,可能会更改远程上的所有文件。 - Sheelpriy

38

如果您想修复最新提交的内容,您可以通过以下操作撤销该提交并将其中的文件取消暂存:

git reset HEAD~1

这将使您的存储库返回到执行git add命令以将文件暂存之前的状态。您的更改将保留在工作目录中。HEAD~1指的是分支当前顶部下面的提交。

如果您想取消 N 次提交,但是保留工作目录中的代码更改:

git reset HEAD~N

如果您想要撤销最新的提交并且不想保留代码更改,您可以进行一次“hard”重置。

git reset --hard HEAD~1
同样地,如果您想丢弃最后的N个提交,并且不想保留代码更改:
git reset --hard HEAD~N

我尝试了这个方法并成功移除了最新的提交,但现在当我推送到远程仓库时,它提示我在推送之前必须先拉取。于是我拉取了一次然后再次推送,但是当我拉取时,我又得到了我刚刚移除的提交,因为我之前已经将其推送到远程。现在该怎么办? - an4s911

25

如果您想删除当前所在的提交,但不想删除数据 -

git reset --soft HEAD~1

如果你想删除当前所在的提交并且希望删除相关数据-

git reset --hard HEAD~1

注意:这些命令只会删除本地提交记录。


最佳答案。简洁明了。 - heysujal

22

要删除本地分支,请使用

git reset --hard HEAD~1

要在远程分支中删除,请使用

git push origin HEAD --force

17

来源: https://gist.github.com/sagarjethi/c07723b2f4fa74ad8bdf229166cf79d8

删除最后一次提交

例如,您的最后一次提交

git push origin +aa61ab32^:master

现在您想要删除此提交,则可以按照以下简单方法进行操作

步骤

  1. 首先将分支重置为当前提交的父级

  2. 强制将其推送到远程。

git reset HEAD^ --hard

git push origin -f

对于特定的提交,您想要重置的是以下内容:

git reset bb676878^ --hard

git push origin -f

17
如果您是IntelliJ用户,那么它的界面非常棒。只需单击一下,您就可以立即看到效果。在MacOS上快速跳转到此位置的方法是:Cmd + 9

输入图片说明


这个问题不是关于IntelliJ,而是关于Git本身的。 - leopinzon
如果您正在使用IntelliJ,这是最快、最简单的方法,但请记住,您必须强制推送,因为您已更改了Git历史记录。 - Ariel Mirra

13

在这里我只发布一个明确的流程来完成此操作

步骤1:使用git log获取提交ID。

git log

enter image description here

第二步:使用git reset回到以前的版本:

git reset --hard <your commit id>

使用 git log origin/master.. 命令可以查看未推送的提交记录。使用 git reset --hard <sha1-commit-id> 命令可以回退到指定提交记录,使用 get reset --hard HEAD~1 命令可以删除最后一次提交记录。 - Nick Dong

11

以上所有命令都将工作树和索引的状态还原为提交之前的状态,但不会恢复存储库的状态。如果您查看它,"removed"提交实际上并没有被删除,它只是不再是当前分支顶端的提交。

我认为没有使用外壳命令删除提交的方法。唯一的方法是从日志和引用日志中删除它,然后执行git prune --expire-now命令。


3
StackOverflow上答案显示的顺序是不固定的。请不要参考“以上所有命令”。让您的回答自成一体。 - Pascal Cuoq
1
这个答案并不完全正确。git prune 实际上是“瓷器”命令之一。此外,你很少需要完全清除你的 reflog(一个用例是从你的 repo 中删除敏感信息,但像我说的那样,这是一个罕见的用例)。更常见的情况是,你会想要在 reflog 中保留旧的提交记录,以防需要恢复数据。请参见《Pro Git》:9.7 Git 内部 - 维护和数据恢复 - user456814

11

如果您想保留历史记录,并显示提交和还原操作,您应该使用:

git revert GIT_COMMIT_HASH

输入解释为什么要回滚,然后:

git push  

当您执行git log命令时,您将看到“错误”的提交以及还原日志消息。


1
是的,但是原帖作者明确表示那不是他们想要的。 - Steve Bennett

10

以下是另一种方法:

检出要还原的分支,然后将本地工作副本重置为您希望成为远程服务器上最新版本的提交(它之后的所有内容都将消失)。在SourceTree中执行此操作,我右键单击并选择“将BRANCHNAME重置为此提交”。我认为命令行是:

git reset --hard COMMIT_HASH

git reset --hard COMMIT_ID

由于您刚从远程仓库检出分支,因此不会有任何本地更改需要担心丢失。但是如果您有,运行该命令将会导致这些更改丢失。

然后转到您的代码仓库本地目录并运行此命令:

git -c diff.mnemonicprefix=false -c core.quotepath=false \
push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME

这将会擦除你本地仓库中当前提交之后的所有提交,但只针对该分支。


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