从Git中的分支中删除提交

hap*_*497 3035 git git-rebase git-reset

我想知道如何删除提交.

通过delete,我的意思是,如果我没有做那个承诺,当我将来做一推,我所做的更改不会推到远程分支.

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

gah*_*ooa 3858

小心: git reset --hard 将删除您的工作目录更改.在运行此命令之前,请务必隐藏要保留的任何本地更改.

假设你正坐在那个提交上,那么这个命令就会搞砸......

git reset --hard HEAD~1
Run Code Online (Sandbox Code Playgroud)

HEAD~1意味着在头之前提交.

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

git reset --hard <sha1-commit-id>
Run Code Online (Sandbox Code Playgroud)

如果你已经推了它,你需要做一个强制推动来摆脱它......

git push origin HEAD --force
Run Code Online (Sandbox Code Playgroud)

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

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


仅供参考 - git reset --hard HEAD如果您想摆脱WORK IN PROGRESS,那就太棒了.它会将您重置为最近的提交,并清除工作树和索引中的所有更改.


最后,如果您需要查找"已删除"的提交,则通常会将其存在,git reflog除非您收集了存储库的垃圾.

  • `HEAD~1`或者只是`HEAD ^`.如果你推,你应该使用`git revert`. (53认同)
  • 但这并不会从提交树中删除更改.OP要求已经提交的提交.如果你'reset --hard`,并检查`log --oneline --all`,那么提交仍然保留在树中.我们如何从树中删除这些提交?谢谢. (17认同)
  • 使用`reset --soft`删除本地提交而不恢复正在进行的工作! (13认同)
  • 显然你也可以使用`HEAD~n`从头脑中"回""n"提交.也许从这一点开始,您可以将`... --hard HEAD`解释为`HEAD~0` =>删除正在进行的工作. (12认同)
  • @ beamrider9 imho git rebase几乎总是删除提交的更好方法(如Greg Hewgill的回答所述) - 尤其是因为rebase确实包含了一个很大的警告,你将删除4realz. (11认同)
  • 很高兴我读了评论,得知这个答案实际上没有回答这个问题,回购中应该没有剩余的东西,"就好像我没有做出那样的承诺." (6认同)
  • 也许这应该修改为提及--soft? (2认同)
  • 你救了我的命。 (2认同)

Gre*_*ill 677

如果您尚未将提交推送到任何位置,则可以使用git rebase -i删除该提交.首先,找出提交的回程(大约).然后做:

git rebase -i HEAD~N
Run Code Online (Sandbox Code Playgroud)

修改~N最后N提交的方法(N例如,必须是数字HEAD~10).然后,您可以编辑Git提供给您的文件以删除违规提交.保存该文件后,Git将重写所有以下提交,就好像您删除的提交不存在一样.

Git Book有一个很好的部分,有关图片和示例的变基础.

小心这一点,因为如果你改变的东西,你已经在别处推,就需要另一种方法,除非你打算做一个力推.

  • @Costa你可以使用`push -f`强制推送并用你的本地替换远程分支.如果它只是你自己的远程回购,没问题.如果其他人在此期间取得了成功,麻烦就开始了. (5认同)
  • 如果你推了它怎么办?(只是我使用远程仓库) (4认同)
  • @dumbledad:使用`rebase -i`,不保留与删除的提交相对应的更改. (4认同)
  • 我添加并提交了一个对GitHub来说太大的数据文件(是的,它可能不应该在源代码库中了;哦,好吧).当我试图推送时,GitHub因为文件太大而拒绝了.我想做的就是撤消这一次提交,同时保存一些其他无关的提交.`git rebase -i HEAD~5`命令*正好*我需要从我的本地仓库中完全删除此提交!谢谢! (3认同)
  • 注意:如果您在最后一批提交中碰巧有--no-ff合并,则重新配置将对其进行屠杀:(这在[this page]的-p下提到(https://www.kernel.org/pub /software/scm/git/docs/git-rebase.html)。问题是,如果将-i替换为-p,您将不再弹出“编辑此提交,压缩该提交”的选项,等等等等。有人知道解决方案吗? (2认同)

180*_*ION 477

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

git rebase -i <commit>~1
Run Code Online (Sandbox Code Playgroud)

这将在-i您想要重置的提交之前的点处以交互模式启动rebase .编辑器将从那时开始列出所有提交.删除包含要删除的提交的行并保存文件.Rebase将完成剩余的工作,仅删除该提交,并将所有其他提交重新放回日志中.

  • 更简单:`git rebase -i HEAD~1` (8认同)
  • 我认为值得注意的是,提交没有被删除,只是从列表中删除.如果你陷入困境,你可以使用[reflog](http://gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html)获取提交. (7认同)
  • 删除与d/drop相同的行吗? (6认同)
  • thx,顺便说一句,如果遇到任何问题(比如空提交)你可以使用`git rebase --continue` (3认同)
  • 哇塞。`git rebase -i HEAD~1` 确实清理了很多 repo!很难确切地说出它做了什么,但整个事情看起来更整洁。有点令人担忧,实际上。 (3认同)
  • 我第一次敢于使用“rebase”并且运行得很顺利。 (2认同)

Rob*_*Rob 328

我正在追加这个答案,因为我不明白为什么那些刚刚尝试提交工作的人会因为使用Git的一些错误而删除所有工作!

如果你想保留你的工作并且只是'撤消'那个提交命令(你在推送回购之前就抓住了):

git reset --soft HEAD~1
Run Code Online (Sandbox Code Playgroud)

除非您想要销毁自上次提交以来正在进行的工作,否则请勿使用--hard标志.

  • `reset --soft`是不失去当前工作的生命救星. (8认同)
  • @Rob,一个例子是当你不小心提交一个包含秘密(例如密码)的文件时,该文件永远不应该在源代码管理中.必须*销毁本地提交*,而不仅仅是撤消,因此它永远不会被推送到服务器. (7认同)
  • 下面是一个原因示例:您在提交的开发服务器上执行一小部分工作.然后事实证明该服务器没有传出HTTPS访问权限,因此您无法将提交推送到任何地方.最容易假装从未发生过,并从本地计算机重做补丁. (5认同)
  • 谢谢.此答案应排名更高或包含在已接受的答案中.删除提交!=恢复提交. (4认同)
  • @KarthikBose 总会有引用日志。即使在 `git reset --hard HEAD~1` 之后,你之前的最新提交也可以通过 reflog 获得(直到你过期);另见此处:http://gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html (2认同)
  • @RandolphCarter:你仍然会丢失任何未提交的更改. (2认同)

rai*_*tes 91

删除整个提交

git rebase -p --onto SHA^ SHA
Run Code Online (Sandbox Code Playgroud)

显然用您想要删除的引用替换"SHA".该命令中的"^"是文字.

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

  • 我怎么能更多地回答这个问题?其他解决方案只是展示如何以交互方式执行或删除顶级提交. (13认同)
  • 它说:“用您要删除的引用替换SHA”,但是该行在其中两次存在SHA。这是我所做的。git rebase -p --onto 5ca8832c120 ^ 5ca8832c120但是什么都没有改变。我是否应该两次使用相同的SHA?如果不是,那么将删除提交的SHA是什么,另一个SHA应该是什么? (4认同)
  • `-p` `[已弃用:使用 --rebase-merges 代替]` (4认同)
  • `-p,--preserve-merges`重新创建合并提交,而不是通过重播合并提交引入的提交来使历史变平。合并冲突解决方案或手动修订以合并提交不会保留。 (2认同)
  • 这是实际的准确答案 (2认同)
  • 具体来说,此方法会删除整个提交,包括文件(在我的情况下不需要) (2认同)
  • @Rubicksman ^ 必须在 Windows(cmd 窗口)上转义 (^^) - /sf/ask/136918981/ (2认同)

Jak*_*ski 50

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

$ git reset --hard HEAD^
Run Code Online (Sandbox Code Playgroud)

(请注意,这也会删除所有未提交的更改;请谨慎使用).

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

$ git revert HEAD
Run Code Online (Sandbox Code Playgroud)

  • 天哪,有些东西神奇地完成了我想要的……这些命令中的哪一个做到了?!?! (2认同)

小智 37

git reset --hard commitId

git push <origin> <branch> --force
Run Code Online (Sandbox Code Playgroud)

PS:CommitId指的是您想要恢复的那个


tk_*_*tk_ 37

假设我们要从repo中删除提交2和4.

commit 0 : b3d92c5
commit 1 : 2c6a45b
commit 2 : <any_hash>
commit 3 : 77b9b82
commit 4 : <any_hash>
Run Code Online (Sandbox Code Playgroud)

注意:您需要拥有对repo的管理权限,因为您正在使用--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 将主站推送到远程仓库.

  • 最后一步应该是“git push -f origin master”,没有选项“--hard” (3认同)
  • 这基本上是正确的,但有点错误。我只是遵循了这个过程,并且不得不稍微调整一下。说明:“commit 0”是最新的提交,“commit 4”是最旧的提交。首先在您不想要的提交之前检查“commit 5”。然后“cherry-pick”“commit 3”,然后“cherry-pick”“commit 1”,然后对“commit 0”执行此操作。然后检查 master 并将其重置为“commit 5”并按照其余步骤操作。 (3认同)
  • 我猜“ commit 0”比“ commit 1”还早。请您告诉我为什么先通过“ commit 3”(通过Cherry-pick)然后通过“ commit 1”进行?签出`b3d92cd`(`commit 0`)之后,我会期望选择“ commit 1`,然后`commit 3`。谢谢。 (2认同)

Ili*_*asT 33

有力地改变历史

假设您不只是想删除最后一次提交,但想要删除最后n次提交的特定提交,请执行以下操作:

git rebase -i HEAD~<number of commits to go back>,所以git rebase -i HEAD~5如果你想看到最后五个提交.

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

附加改变历史

试试git revert <commit hash>.Revert将创建一个撤消指定提交的提交.

  • 对我来说 drop 被定义为关键字,但执行 drop 似乎并没有从历史记录中删除提交。但是,从交互式 rebase 中删除了该行。 (2认同)

Jav*_* C. 33

[快速回答]

你有很多选择,例如:


Anu*_*rma 30

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

git reset HEAD~1
Run Code Online (Sandbox Code Playgroud)

这将使您的存储库返回到分阶段执行文件的git add命令之前的状态.您的更改将在您的工作目录中.HEAD~1指的是分支当前尖端下面的提交.

如果要取消提交N提交,请在工作目录中保持代码更改:

git reset HEAD~N
Run Code Online (Sandbox Code Playgroud)

如果你想摆脱最新的提交,并且不想保持代码更改,你可以进行"硬"重置.

git reset --hard HEAD~1
Run Code Online (Sandbox Code Playgroud)

同样,如果要丢弃最后的N次提交,并且不想保持代码更改:

git reset --hard HEAD~N
Run Code Online (Sandbox Code Playgroud)


nav*_*gar 26

如果您想删除当前正在进行的提交但不想删除数据-

git reset --soft HEAD~1
Run Code Online (Sandbox Code Playgroud)

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

git reset --hard HEAD~1
Run Code Online (Sandbox Code Playgroud)

PS:这些命令只会删除本地提交。


Siv*_*een 19

git rebase -i HEAD~2
Run Code Online (Sandbox Code Playgroud)

这里'2'是您要重新设置的提交数.

'git rebase -i HEAD`
Run Code Online (Sandbox Code Playgroud)

如果你想重新提交所有提交.

然后,您将能够选择其中一个选项.

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

这些线可以重新排序; 它们是从上到下执行的.如果你在这里删除一行,那么COMMIT将会丢失.但是,如果删除所有内容,则将终止rebase.请注意,空提交已注释掉

您可以使用选项"d"或删除具有提交的行来删除该提交.


Sau*_*ahu 17

如果您是IntelliJ用户,那么该界面简直太棒了。只需单击一下,即可立即看到效果。到此位置的快捷方式:Cmd + 9在 MacOS 上。

在此输入图像描述


the*_*tar 16

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

git reset --hard HEAD~1
Run Code Online (Sandbox Code Playgroud)

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

git push origin HEAD --force
Run Code Online (Sandbox Code Playgroud)


Fra*_*ank 13

在这里我只是发布一个明确的管道来做到这一点

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

git log
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

Step2:使用 git reset 返回到之前的版本:

git reset --hard <your commit id>
Run Code Online (Sandbox Code Playgroud)


sag*_*thi 10

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

删除最后一次提交

例如您的最后一次提交

git push origin + aa61ab32 ^:master

现在您要删除此提交,然后执行以下简单操作

脚步

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

  2. 强制将其推到遥控器上。

git reset HEAD^ --hard

git push origin -f
Run Code Online (Sandbox Code Playgroud)

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

git reset bb676878^ --hard

git push origin -f
Run Code Online (Sandbox Code Playgroud)


Com*_*ast 9

这是另一种方法:

签出要还原的分支,然后将本地工作副本重置回您希望成为远程服务器上最新版本的提交(之后的所有内容将再次发生).为此,在SourceTree中我右键单击并选择"将BRANCHNAME重置为此提交".我认为命令行是:

git reset --hard COMMIT_ID
Run Code Online (Sandbox Code Playgroud)

由于您刚刚从远程检出了您的分支,因此您不会有任何本地更改以担心丢失.但如果你这样做会失去它们.

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

git -c diff.mnemonicprefix=false -c core.quotepath=false \
push -v -f --tags REPOSITORY_NAME BRANCHNAME:BRANCHNAME
Run Code Online (Sandbox Code Playgroud)

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


Leo*_*Leo 9

错误:

git rebase -i --root是我的分支,无知地认为我可以改写与主服务器不同的第一个提交(GitHub for Windows默认视图是与master的比较,隐藏它的全部).

我长大了一个硅谷的胡子,而900多个提交加载到Sublime.在没有任何变化的情况下退出,我对电池进行了充电然后继续刮胡子,因为所有900多个人提交的都是不加协商的 - 重置他们的提交时间到现在.

决定击败Git并保留原始时间,我删除了这个本地存储库并从远程重新克隆.

现在它重新添加了一个最近不需要的提交给master我希望删除,所以继续这样做.

耗尽选项:

我不希望git revert- 它会创建一个额外的提交,让Git占上风.

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

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

思考过后git reset --hard <SHA>,我更新了另一个分支掌握和1 ... 2 ...噗!提交回来了--Git赢了.

检查回来掌握,时间尝试git rebase -i <SHA>,然后删除线...无济于事,可悲的说." 如果你在这里删除一条线,那将会失败 ".啊...... 在2.8.3发行说明中掩盖了新功能巨魔n00b.

解决方案:

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

为了验证,我检查了另一个分支,瞧 - 没有隐藏提交从主服务器获取/拉取.

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

祝你好运


Ang*_*tti 8

上面的所有命令都会在进行提交之前恢复工作树和索引的状态,但不会恢复存储库的状态.如果你看一下,"删除"提交实际上并没有被删除,它根本就不是当前分支顶端的提交.

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

  • StackOverflow 上答案的显示顺序并不固定。请不要参考“以上所有命令”。让你自己的答案自成一体。 (3认同)

Pwn*_*rar 7

如果你搞砸了你的最后一次提交(错误的消息,忘记添加一些更改)并希望在将其推送到公共仓库之前修复它,为什么不使用:

git commit --amend -m "New message here"
Run Code Online (Sandbox Code Playgroud)

如果你有新的阶段性更改,它们将与最后一次提交(你试图摆脱)相结合,并将替换该提交.

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

如果您希望使用先前的提交消息,也可以传递'--no-edit'选项而不是'-m'.

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

  • 这不是OP所要的。 (2认同)

Pau*_*lgo 7

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

git revert GIT_COMMIT_HASH
Run Code Online (Sandbox Code Playgroud)

输入消息,解释你为什么要还原,然后:

git push  
Run Code Online (Sandbox Code Playgroud)

当您发出时,git log您将看到"错误"提交和还原日志消息.


小智 7

git reset --hard HEAD~1
您现在将处于先前的位置。拉树枝。推送新代码。提交将从 git 中删除


Ser*_*aka 6

我已经推了。需要远程返回一些提交。已经尝试了许多变化,但只有这样,从贾斯汀通过git的衬套工作对我罚款:

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force
Run Code Online (Sandbox Code Playgroud)


Jus*_*tin 5

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

git reset --hard $GIT_COMMIT_HASH_HERE
git push origin HEAD --force
Run Code Online (Sandbox Code Playgroud)

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

git reset --hard origin/master
Run Code Online (Sandbox Code Playgroud)


Chr*_*Sim 5

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

git reset --hard HEAD~1

git push -f origin
Run Code Online (Sandbox Code Playgroud)

希望这个帮助


小智 5

在本地分支上重置

git reset --hard HEAD~<Number of commit> So git reset --hard HEAD~3
Run Code Online (Sandbox Code Playgroud)

强制推送到原点

git push -f origin
Run Code Online (Sandbox Code Playgroud)


Sha*_*jed 5

// display git commit log    
$ git log --pretty=oneline --abbrev-commit

// show last two commit and open in your default editor
// then delete second commit line and save it
$ git rebase -i HEAD~2
Run Code Online (Sandbox Code Playgroud)

参考:如何在 git、本地和远程删除提交