如何删除未推送的 Git 提交?

1498

我不小心提交到了错误的分支。如何删除这个提交?

7个回答

2863

删除最近的提交,同时保留你所完成的工作:

git reset --soft HEAD~1

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

git reset --hard HEAD~1

28
确保 HEAD 指向分支。(先检查一下) - Frank Schwieterman
203
请确保 HEAD~1 是提交记录......你也可以执行 git reset --hard origin - Daenyth
17
为什么我的 git remote 命令列出了 origin,但是运行 git reset --hard origin 命令时却显示 fatal: ambiguous argument 'origin': unknown revision or path not in the working tree. 的错误信息? - trss
11
太棒了,这简直救了我的命。 - NinjaBoy
2
git reset HEAD~1 也会保留您所有的更改,但是会让您留下一个空的索引而不是保留所有内容(就像 --soft 选项一样)。 - Holloway
显示剩余11条评论

523

我不明白为什么我找到的最佳答案只在评论中!(由Daenyth得到86个赞)

git reset --hard origin

这个命令将会同步本地仓库和远程仓库,清除你在本地所做的任何更改。 你也可以按照Cleary在评论中建议的方式执行以下操作以获取与原始分支完全相同的分支。

git reset --hard origin/<branch>

35
谢谢您,稍微扩展一下解释:对于特定的分支,可以使用以下命令:git reset --hard origin/<branch> - cleary
23
如果你想要消除提交但保留本地工作,可以使用git reset --soft origin/<branch>命令。 - riverhorse
3
我收到了 fatal: ambiguous argument 'origin': unknown revision or path not in the working tree. 的错误提示,你需要指定分支,例如:git reset --hard origin/feature/my-cool-stuff - Kip
4
太棒了!这真的有效,不像“被接受”的答案只是分离头部然后让你挂着。 - mae
你如何链接到评论? - user5306470

66

如果只有一个提交,不要删除它,使用git cherry-pick就足够了。

但是如果你在错误的分支上有多个提交,那么git rebase --onto就很有用:

假设你有这个:

 x--x--x--x <-- master
           \
            -y--y--m--m <- y branch, with commits which should have been on master

如果您愿意,可以标记master并将其移动到您想要的位置:

 git checkout master
 git branch tmp
 git checkout y
 git branch -f master

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- y branch, master branch

重置你的分支到正确的位置:

 git checkout y
 git reset --hard HEAD~2 # ~1 in your case, 
                         # or ~n, n = number of commits to cancel

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- master branch
                ^
                |
                -- y branch

最后,将您的提交移动(重新应用它们,创建全新的提交)

 git rebase --onto tmp y master
 git branch -D tmp


 x--x--x--x--m'--m' <-- master
           \
            -y--y <- y branch

2
不幸的是,那不是问题。 - KatariaA
5
@KatariaA 这是一个有效的替代方案,可以避免删除在错误分支上提交的好的提交,并且会对其他遇到相同情况的人有所帮助。 - VonC

23

执行git rebase -i FAR_ENOUGH_BACK命令,并删除你不想要的提交行。


1
如果您最终删除了所有提交,可以将“noop”添加为操作,或者rebase不执行任何操作。这是我首选的版本,因为它非常清楚您正在更改什么。 - Scott Carlson

8
如果您想将该提交移动到另一个分支,请获取有关该提交的SHA值。
git rev-parse HEAD

然后切换当前分支。

git checkout other-branch

并将提交内容 cherry-pickother-branch

git cherry-pick <sha-of-the-commit>

根据我的经验,这个操作并没有撤销原始分支的提交,因此需要在之后执行 git reset --hard HEAD~1 命令。我认为使用 reset --soft 然后切换分支并再次提交会节省额外的工作。不过我大多数情况下都是使用SourceTree完成基本操作,只有在出现错误后才通过命令行进行操作。 - jusopi

8

以下命令可以帮助我,它会放弃所有本地提交的更改,并将本地重置为与远程origin/master分支相同的状态。

git reset --hard origin


2
这是 https://dev59.com/A3A75IYBdhLWcg3wm6ix#54323316 的副本。 - SiHa
我没有注意到那个响应,我尝试了那个命令,并且它对我有效,所以我相应地发布了响应。 - Atul Sureka

3
作为参考,我认为你不仅可以使用git reset –hard命令"硬重置"当前分支的提交记录,也可以使用以下命令:
git checkout -B <branch-name> <SHA>

实际上,如果你不关心检出,你可以使用以下命令将分支设置为任何你想要的:

git branch -f <branch-name> <SHA>

这是一种编程方式来从分支中删除提交,例如,为了将新的提交复制到它上面(使用rebase)。
假设您有一个与master断开连接的分支,因为您已经从其他位置获取了源代码并将其转储到该分支中。
现在您有一个应用了更改的分支,让我们称之为“topic”。
现在,您将创建一个“topic”分支的副本,并将其rebase到坐落在“dump”分支中的源代码转储。
git branch topic_duplicate topic
git rebase --onto dump master topic_duplicate

现在你的更改会在基于“dump”起点的分支“topic_duplicate”中重新应用,但仅限于自“master”以来发生的提交。因此,你自“master”以来的更改现在会在“dump”的顶部重新应用,但结果最终出现在“topic_duplicate”中。
接下来,你可以通过执行以下操作将“dump”替换为“topic_duplicate”:
git branch -f dump topic_duplicate
git branch -D topic_duplicate

或使用

git branch -M topic_duplicate dump

或者只需丢弃垃圾信息

git branch -D dump

也许您可以在清除当前的“topic_duplicate”后进行精选。
我的意思是,如果您想基于不同的祖先更新当前的“duplicate”分支,则必须首先通过执行`git reset --hard `或`git branch -f topic_duplicate `来删除以前“cherrypicked”的提交,然后通过重新贴标签或挑选复制其他提交(从主题目标分支)。
重新贴标签只适用于已经有提交的分支,因此每次想执行这个命令时,需要复制您的主题分支。
挑选复制更加容易:
git cherry-pick master..topic

所以整个过程将变成:
git reset --hard <latest-commit-to-keep>
git cherry-pick master..topic

当你切换到主题重复分支时,会移除之前从当前重复分支中挑选的提交,并且只重新应用“主题”中发生的所有更改来覆盖你当前的“dump”(不同的祖先)。这似乎是一种相当方便的方法,可以基于“真正的”上游主分支进行开发,同时使用不同的“下游”主分支来检查本地更改是否仍然适用。或者,您可以生成差异,然后将其应用于任何Git源树之外。但以这种方式,您可以保持一个基于您的发行版版本的最新修改(补丁)版本,而实际开发则是针对真正的上游主分支。
因此,只是为了演示:
- 重置将使您的分支指向另一个提交(--hard也会检出上一个提交,--soft会将添加的文件保留在索引中(如果再次提交,则会提交),默认值(--mixed)不会检出先前的提交(清除本地更改),但会清除索引(尚未添加任何内容进行提交) - 你可以强制一个分支指向一个不同的提交 - 你可以在立即检出该提交的同时执行此操作 - 变基作用于当前分支中存在的提交 - 挑选表示从不同的分支进行复制
希望这能帮助某人。我原本想重写这个,但现在无法管理。致意。

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