从Git中的分支删除提交


3230

我想知道如何删除提交。

通过delete,我的意思是好像我没有进行该提交一样,并且将来进行推送时,所做的更改将不会推送到远程分支。

我读了git help,我认为我应该使用的命令是git reset --hard HEAD。它是否正确?


41
我认为这不是Git撤消上一次提交的副本,因为它询问如何从分支中删除任何提交。我也认为没有答案实际上解决了这个问题。他们都倒回过去的提交,而不是cherry-pickdelete单个提交,可能发生在不久前。
克里斯(Chris)

12
@Chris,答案git rebase -i HEAD~10确实解决了这个问题,因为它确实允许您随意选择要删除的提交。Git会在您指定的范围内一次应用提交,而忽略您已从日志中删除的提交。我今天使用此命令摆脱了对存储库的第二次和第三次最近提交,同时保留了第一条。我同意其他答案都不令人满意。
MST

@MST是的,我应该说,公认的答案中的所有选项都不能解决这个问题,但是您绝对正确-该命令似乎有效
Chris

Answers:


4122

小心: git reset --hard 将删除您的工作目录更改。在运行此命令之前,请确保存储要保留的所有本地更改

假设您正坐在该提交上,那么此命令将使其失效...

git reset --hard HEAD~1

HEAD~1方法的头前提交。

或者,您可以查看的输出git log,找到要备份到的提交的提交ID,然后执行以下操作:

git reset --hard <sha1-commit-id>

如果您已经推过它,则将需要用力推动才能摆脱它...

git push origin HEAD --force

但是,如果其他人可能已经撤消了,那么您最好开始新的分支。因为当他们拉动它时,它只会将其合并到他们的工作中,并且您会再次将其推回去。

如果已经推送过,最好使用git revert来创建一个“镜像”提交,以撤消更改。但是,两个提交都将在日志中。


仅供参考- git reset --hard HEAD如果您想摆脱正在进行的工作,那就太好了。它会将您重置为最新提交,并清除工作树和索引中的所有更改。


最后,如果您需要查找“删除”的提交,则git reflog除非您已对存储库进行垃圾收集,否则通常会存在该提交。


59
HEAD~1或者只是HEAD^。如果按下,则应git revert改用。
2009年

13
显然,您也可以使用HEAD~n“回头” n提交。也许从这一点上,您也可以将其解释... --hard HEADHEAD~0=>删除进行中的工作。
nuala 2012年

13
@ beamrider9 imho git rebase几乎总是删除提交的更好方法(如Greg Hewgill的答案所述)-尤其重要的是,因为rebase确实包含一个大警告,即您将删除4realz。
Noah Sussman '10

20
但是,这不会从提交树中删除更改。OP要求已提交。如果是reset --hard,然后检查log --oneline --all,则提交仍保留在树中。我们如何从树中删除这些提交?谢谢。
iGbanam

17
用于reset --soft删除本地提交而无需还原正在进行的工作!

704

如果尚未将提交推送到任何地方,则可以使用git rebase -i删除该提交。首先,找出该提交的距离(大约)。然后做:

git rebase -i HEAD~N

~N方法将最后一次N提交作为基准(N例如,必须为数字HEAD~10)。然后,您可以编辑Git呈现给您的文件以删除有问题的提交。保存该文件后,Git将重写以下所有提交,就好像您删除的提交不存在一样。

《 Git书》中有一个很好的章节,介绍了如何根据图片和示例进行基础调整。

但是请务必小心,因为如果您更改了推到其他位置的内容,则除非您打算进行强制推入,否则将需要另一种方法。


2
注意:如果在最后一批提交中碰巧有--no-ff合并,则rebase将对它们进行屠杀:(这是在此页的 -p下提到的。问题是,如果将-i替换为-p,您不再会看到“编辑此提交,压缩该提交”等选项的弹出窗口。有人知道解决方案吗?
Bukov

4
如果您推送了该怎么办?(只是我使用远程存储库)
哥斯塔

6
@Costa可以push -f用来强制推送,并将远程分支替换为本地分支。如果这只是您自己的远程仓库,那没问题。如果同时有人抓紧时间,麻烦就开始了。
格雷格·休吉尔

3
我添加并提交了一个对于GitHub来说太大的数据文件(是的,无论如何它可能都不应该在源代码仓库中;哦,很好)。当我尝试推送时,GitHub因文件太大而拒绝了。我要做的就是撤消这一提交,同时保存随后的其他一些无关的提交。该git rebase -i HEAD~5命令正是我从本地存储库中完全删除此提交所需要的命令!谢谢!
aldo

4
@dumbledad:使用时rebase -i,不会保留与已删除的提交对应的更改。
格雷格·休吉尔

517

另一种可能性是我个人最喜欢的命令之一:

git rebase -i <commit>~1

这将在-i您要修改的提交之前的某个点以交互模式启动rebase 。此后,编辑器将开始列出所有提交。删除包含要删除的提交的行,然后保存文件。Rebase将完成其余工作,仅删除该提交,并将所有其他提交重播到日志中。


3
thx,顺便说一句,如果您遇到任何问题(例如空提交),都可以使用git rebase --continue
realgt 2012年

8
更容易: git rebase -i HEAD~1
mmell 2013年

2
Wowzers。git rebase -i HEAD~1真的清理了很多仓库!很难确切地知道它做了什么,但是整个事情看起来很整洁。实际上有点令人震惊。
查尔斯·伍德

7
我认为值得注意的是,提交并未被删除,只是从列表中删除了。如果您搞砸了,可以使用reflog取回提交。
Zaz 2015年

6
删除行是否与d / drop相同?
狮子座

344

我要附加这个答案,因为我不明白为什么任何刚尝试提交工作的人都会因为使用Git出错而希望删除所有工作!

如果您想保留工作并只是“撤消”该提交命令(您在推送回购之前就被捕获):

git reset --soft HEAD~1

除非要破坏自上次提交以来正在进行的工作,否则不要使用--hard标志。


5
这是为什么的一个示例:您在提交的开发服务器上做一小部分工作。然后证明该服务器没有传出的HTTPS访问权限,因此您无法将提交推送到任何地方。最容易假装它从未发生过,然后从本地计算机重做补丁。
史蒂夫·贝内特

1
@KarthikBose总是会有reflog。即使git reset --hard HEAD~1您之前的最新提交可以通过reflog获得(直到您将其终止);又见这里:gitready.com/intermediate/2009/02/09/...
codeling

4
谢谢。该答案应排在更高的位置或包含在接受的答案中。删除提交!=恢复提交。
Alsciende 2014年

2
@RandolphCarter:您仍然会丢失所有未提交的更改。
naught101 '09

7
@Rob,一个例子是,当您不小心提交了一个包含秘密(例如密码)的文件时,该秘密不应该在源代码控制中。本地提交必须被销毁,而不仅仅是撤销,因此它永远不会被推送到服务器。
鲍勃·迈耶斯

141

删除整个提交

git rebase -p --onto SHA^ SHA

显然,将“ SHA”替换为您要删除的引用。该命令中的“ ^”为文字。

http://sethrobertson.github.io/GitFixUm/fixup.html#change_deep


26
我该如何进一步回答这个问题???其他解决方案仅展示了如何以交互方式进行操作或删除顶部提交。
ribamar

5
-p, --preserve-merges 重新创建合并提交,而不是通过重播合并提交引入的提交来变平历史记录。合并冲突解决方案或手动修订以合并提交不会保留。
raittes

5
这是实际的准确答案
Hamman Samuel

9
它说:“用您要删除的引用替换SHA”,但是该行在其中两次存在SHA。这是我所做的。git rebase -p --onto 5ca8832c120 ^ 5ca8832c120但是什么都没有改变。我是否应该两次使用相同的SHA?如果不是,那么将删除提交的SHA是什么,另一个SHA应该是什么?
拉比克斯曼

3
哇,它完美地工作了!这应该是公认的答案!
Liran H

51

如果您未发布更改,则要删除最新提交,可以执行

$ git reset --hard HEAD^

(请注意,这还将删除所有未提交的更改;请谨慎使用)。

如果您已经发布了要删除的提交,请使用git revert

$ git revert HEAD

那没用。当我git log时,一切仍然存在,无论我为什么这样做,只会添加更多的提交。我想清理历史。
2014年

@Costa:什么不起作用(即您使用了哪个版本),以及您如何git登录?
JakubNarębski2014年

我已经在此问答中尝试了几乎所有内容。(我最近尝试过git revert HEAD)我的git日志:tree = log --all --graph --format=format:'%C(bold blue)%h%C(reset) %C(dim black)%s%C(reset)%C(bold red)%d%C(reset) %C(green)by %an, %ar%C(reset)'
Costa

1
我只想删除提交(就像它们根本不存在一样)。我开始了一些奇怪的编码冒险,进行了几次新的提交,但最终都被浪费了。我怎样才能从git日志中删除这些内容?
2014年

2
真是不可思议的东西完全符合我的要求。。。
2014年

44

假设我们要从仓库中删除提交2和提交4。

commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>

注意:由于您正在使用和,因此您需要对该存储库具有管理员权限--hard-f

  • git checkout b3d92c5 签出最后可用的提交。
  • git checkout -b repair 创建一个新分支进行处理。
  • git cherry-pick 77b9b82 运行提交3。
  • git cherry-pick 2c6a45b 运行提交1。
  • git checkout master 结帐大师。
  • git reset --hard b3d92c5 将master重置为上一次可用的提交。
  • git merge repair 将我们的新分支合并到master。
  • git push -f origin master 将master推送到远程仓库。

1
最后一步应该git push -f origin master是没有选择--hard
Vivex

2
我想commit 0比早commit 1。请您告诉我为什么先经过commit 3(樱桃挑剔)再经过commit 1?结帐后b3d92cdcommit 0),我希望樱桃采摘commit 1,然后commit 3。谢谢。
Jarek C

@JarekC我认为最高级的提交是这里的最新提交,除非我看到有问题...
Jeff Huijsmans

41
git reset --hard commitId

git push <origin> <branch> --force

PS:CommitId指您要还原为的那个


git push --force <来源> <分支名称>。如不提及分支名称,它可能会更改远程上的所有文件。
sheelpriy

39

强制更改历史记录

假设您不仅要删除最后一个提交,还想删除最后n个提交的特定提交,请执行以下操作:

git rebase -i HEAD~<number of commits to go back>,因此git rebase -i HEAD~5如果您想查看最后五个提交。

然后在文本编辑器中字改变pickdrop旁边的每一个承诺,你想删除。保存并退出编辑器。瞧!

加性更改历史

尝试git revert <commit hash>Revert将创建一个新的提交,该提交将撤消指定的提交。


drop关键字未定义。要删除提交,只需删除整行。
Shayan Salehian

1
对我来说,drop被定义为一个关键字,但是执行drop似乎并没有从历史记录中删除提交。但是,从交互式资源库中删除了该行。
亚当·帕金

这正是我所需要的。效果很好;谢谢!
diekunstderfuge

30

如果要修复最新的提交,可以执行以下操作来撤消提交,并取消暂存其中的文件:

git reset HEAD~1

这将使您的存储库恢复到暂存文件的git add命令之前的状态。您所做的更改将在您的工作目录中。HEAD〜1是指分支当前尖端下方的提交。

如果要取消提交N次提交,但将代码更改保留在工作目录中:

git reset HEAD~N

如果您想摆脱最近的提交,并且不想保留代码更改,则可以执行“硬”重置。

git reset --hard HEAD~1

同样,如果您要放弃最后的N次提交,并且不想保留代码更改,请执行以下操作:

git reset --hard HEAD~N

22
git rebase -i HEAD~2

这里的“ 2”是您要重新设置基准的提交数。

'git rebase -i HEAD`

如果您想重新设置所有提交。

然后,您将可以选择以下选项之一。

p, pick = use commit

r, reword = use commit, but edit the commit message

e, edit = use commit, but stop for amending

s, squash = use commit, but meld into previous commit

f, fixup = like "squash", but discard this commit's log message

x, exec = run command (the rest of the line) using shell

d, drop = remove commit

这些行可以重新排序;它们从上到下执行。如果您在此处删除一行,那将丢失。但是,如果删除所有内容,则重新定位将中止。请注意,空提交已被注释掉

您只需使用选项“ d”或删除包含您的提交的行即可删除该提交。


在最新的git版本中,没有其他选项d。您只需要从基线中删除带有提交的行即可将其删除。
Oleg Abrazhaev

17

要在本地分支中删除,请使用

git reset --hard HEAD~1

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

git push origin HEAD --force

12

[快速回答]

您有许多选择,例如:

  • 选择1:

    git rebase -i <YourCommitId>~1
    

    将YourCommitId更改为要还原为的提交编号。

  • 选择2:

    git reset --hard YourCommitId
    git push <origin> <branch> --force
    

    将YourCommitId更改为要还原为的提交编号。

    我不建议使用此选项,因为您可能会丢失正在进行的工作。

  • 选择3:

    git reset --soft HEAD~1
    

    您可以继续工作,仅撤消提交。


谢谢(谢谢)
哈比卜·雷曼

11

来源: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

9

这是执行此操作的另一种方法:

签出要还原的分支,然后将本地工作副本重置回您要成为远程服务器上最新提交的提交(此操作之后的所有操作都会再见)。为此,我在SourceTree中右键单击,然后选择“将BRANCHNAME重置为此提交”。我认为命令行是:

git reset --hard COMMIT_ID

由于您只是从远程签出分支机构,因此无需进行任何本地更改即可担心丢失。但是,如果您这样做,将会丢失它们。

然后导航到存储库的本地目录并运行以下命令:

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

这将删除本地存储库中当前提交之后的所有提交,但仅针对该分支。


9

这个错误:

我开git rebase -i --root了分支,无知地想我可以改写与主服务器不同的第一个提交(WindowsGitHub默认视图是与主服务器的比较,隐藏了它的全部内容)。

当我将900多个提交加载到Sublime时,我长出了硅谷胡须。退出时没有任何变化,我为电池充电,然后开始剃须,因为所有900多个个人提交都坚定地重新设置了基础-将其提交时间重置为现在。

为了击败Git并保留原始时间,我删除了此本地存储库并从远程重新克隆。

现在,它重新添加了我希望删除的对master的最新不需要的提交,因此按以下步骤进行。

穷尽所有选项:

我不希望git revert-它会创建一个额外的提交,从而使Git占上风。

git reset --hard HEAD在检查了之后reflog,什么也没做,最后也是唯一HEAD的克隆-Git获胜。

为了获得最新的SHA,我检查了github.com上的远程存储库-小胜利。

经过思考后git reset --hard <SHA>,我将另一个分支更新为master和1 ... 2 ... poof!提交又回来了-Git赢了。

检查回给主人,时间去尝试git rebase -i <SHA>,然后取出线......都无济于事,痛心地说。“ 如果您在此处删除一行,则该行将丢失 ”。啊...关于新功能,在2.8.3发行说明中拖了n00b

解决方案:

git rebase -i <SHA>然后d, drop = remove commit

为了进行验证,我签出了另一个分支,然后瞧-没有隐藏的提交要从主服务器提取/拉取。

https://twitter.com/holman/status/706006896273063936

祝你有美好的一天。


8

上面的所有命令都将恢复提交前的工作树和索引状态,但不恢复存储库的状态。如果看一下,“已删除”的提交实际上并没有被删除,它根本不是当前分支顶端的那个。

我认为没有办法用瓷器命令删除提交。唯一的方法是将其从日志和reflog中删除,然后执行一个git prune --expire -now


1
答案在StackOverflow上显示的顺序不固定。请不要参考“以上所有命令”。使自己的答案独立。
Pascal Cuoq 2014年

这个答案并不完全正确。git prune 实际上是“瓷器”命令之一。另外,很少会想要完全清除reflog(一种用例是从您的存储库中删除敏感信息,但就像我说的那样,这是一种罕见的用例)。通常,您需要将旧提交保留在reflog中,以防万一您需要恢复数据。请参阅Pro Git:9.7 Git内部-维护和数据恢复

8

如果要保留历史记录,显示提交和还原,则应使用:

git revert GIT_COMMIT_HASH

输入说明为什么要还原的消息,然后:

git push  

发出问题时,git log您会同时看到“错误”的提交和还原日志消息。


是的,但是OP很清楚那不是他们想要的。
史蒂夫·贝内特

7

如果您只是弄乱了最后一次提交(错误消息,忘记添加一些更改),并且想在将其提交到公共仓库之前对其进行修复,为什么不使用:

git commit --amend -m "New message here"

如果您有新上演的更改,它们将与上一次提交(您要摆脱的更改)结合在一起,并将替换该提交。

当然,如果您在提交后修改了提交,那么您将重写历史记录,因此,如果这样做,请务必理解其含义。

如果您希望使用上一次提交的消息,也可以通过'--no-edit'选项而不是'-m'。

文件:http//git-scm.com/docs/git-commit.html


2
这不是OP所要求的。
史蒂夫·贝内特

5

如果已经推送,则首先在HEAD ($ GIT_COMMIT_HASH_HERE)处找到要提交的提交,然后运行以下命令:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force

然后,每个仓库都已被克隆,运行:

git reset --hard origin/master

5

我提交并推送时通常执行的操作(如果有人推送了他的提交,则可以解决问题):

git reset --hard HEAD~1

git push -f origin

希望这个帮助




3

将您的代码备份到temp文件夹中。以下命令将与服务器重置相同。

git reset --hard HEAD
git clean -f
git pull

如果您想保留更改,并删除最近的提交

git reset --soft HEAD^
git pull


2

删除本地提交

如上图所示,我想删除还原“测试更改2”提交(SHA1 ID:015b5220c50e3dfbb1063f23789d92ae1d3481a2(您可以通过gitk在git bash中使用命令来获得SHA1 ID ))。

为此,我可以使用(以下所有命令仅在本地有效。删除后需要按入):

  1. git reset --hard 515b5220c50e3dfbb1063f23789d92ae1d3481a2//将您备份到该提交(测试更改4提交的SHA1 ID 为515b5220c50e3dfbb1063f23789d92ae1d3481a2
  2. git reset --hard HEAD~1 //在一次提交之前备份您。
  3. git reset --hard HEAD^ //从git删除最后一次提交

删除后:

删除后提交


2

git reset --hard HEAD~1
您现在将在前任负责人。拉分支。推送新代码。提交将从git中删除


除非您已经推送了更改。在这种情况下,硬重置将无法清理您的遥控器。在这种情况下,重新存储是个不错的选择
c0der512

1

git reset --hard

git push origin HEAD --force

如果对一个或多个提交进行了标记,请首先删除该标记。否则,不会删除带标记的提交。



0

以我为例,我针对此目的的魔术代码是这样的:

git reset --hard @{u}

测试一下,然后告诉我。我尝试了几种不同的方法,但这是唯一对我有所帮助的方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.