ChatGPT解决这个技术问题 Extra ChatGPT

如何从分支中删除提交?

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

我认为这 notGit undo last commit 的副本,因为它询问如何从分支中删除 any 提交。我也认为没有一个答案真正解决了这个问题。它们都回退最后一次提交,而不是 cherry-pickdelete 可能在不久前发生的单个提交。
@Chris,git rebase -i HEAD~10 的答案确实解决了这个问题,因为它确实让您可以任意选择要删除的提交。 Git 会逐一应用您指定的范围内的提交,而忽略您已从日志中删除的提交。我今天使用此命令来摆脱对我的 repo 的第二次和第三次最近的提交,同时保留最高的提交。我同意其他答案都不令人满意。
@MST是的,我应该说,接受的答案中没有一个选项可以解决这个问题,但你是绝对正确的 - 该命令似乎有效
我认为 git reset --soft HEAD~1 正是您所需要的。在这种情况下,您将撤消提交并保存您的工作。 reset --hard 将完全删除提交。
命令:git log |头-n 1 | git 还原

A
Arslan Ali

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

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

git reset --hard HEAD~1

HEAD~1 表示 head 之前的提交。

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

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

如果你已经推了它,你需要用力推才能摆脱它......

git push origin HEAD --force

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

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

仅供参考 - 如果您想摆脱 WORK IN PROGRESS,git reset --hard HEAD 非常棒。它会将您重置回最近的提交,并删除工作树和索引中的所有更改。

最后,如果您需要找到您“删除”的提交,它通常出现在 git reflog 中,除非您已对存储库进行垃圾收集。


HEAD~1 或只是 HEAD^。如果你推送,你应该使用 git revert 代替。
显然,您也可以使用 HEAD~n 从您的脑海中“返回”n 提交。也许从这一点您可以将 ... --hard HEAD 也解释为 HEAD~0 =>删除正在进行的工作。
@beamrider9 imho git rebase 几乎总是删除提交的更好方法(如 Greg Hewgill 的回答中所述)——尤其是因为 rebase 实际上包含一个大警告,即您将删除 4realz 的东西。
不过,这不会从提交树中删除更改。 OP 要求已经提交。如果您选择 reset --hard 并选中 log --oneline --all,则提交仍保留在树中。我们如何从树中删除这些提交?谢谢。
使用 reset --soft 删除本地提交而不恢复正在进行的工作!
J
James Ko

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

git rebase -i HEAD~N

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

Git Book 有一个很好的section on rebasing,其中包含图片和示例。

不过要小心这一点,因为如果您更改了已在其他地方推送的内容,则需要另一种方法,除非您打算进行强制推送。


注意:如果您在最后一批提交中碰巧有任何 --no-ff 合并,rebase 将屠杀它们 :( 这在 this page 的 -p 下提到。问题是,如果您将 -i 替换为 -p ,您不再会弹出“编辑此提交,压缩那个”等选项。有人知道解决方案吗?
如果你推了它怎么办? (只有我使用远程仓库)
@Costa,您可以使用 push -f 强制推送并将远程分支替换为本地分支。如果它只是你自己的远程仓库,没问题。如果其他人在此期间取来了,麻烦就开始了。
我添加并提交了一个对于 GitHub 来说太大的数据文件(是的,它可能不应该在源代码库中;哦,好吧)。当我尝试推送时,由于文件太大,GitHub 拒绝了。我想做的只是撤消这一次提交,同时保存随后的其他一些不相关的提交。 git rebase -i HEAD~5 命令正是从我的本地存储库中完全删除此提交所需要的!谢谢!
@dumbledad:使用 rebase -i,与已删除提交对应的更改不会保留。
1
1800 INFORMATION

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

git rebase -i <commit>~1

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


thx,顺便说一句,如果您遇到任何问题(例如空提交),您可以使用 git rebase --continue
更简单:git rebase -i HEAD~1
哇塞。 git rebase -i HEAD~1 真的清理了很多回购!很难确切地说它做了什么,但整个事情看起来更整洁。实际上,有点令人担忧。
我认为值得注意的是,提交并没有被删除,只是从列表中删除。如果您搞砸了,您可以使用 reflog 取回提交。
删除行和d/drop一样吗?
R
Rob

我附上了这个答案,因为我不明白为什么任何刚刚尝试提交工作的人会因为使用 Git 的一些错误而想要删除所有这些工作!

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

git reset --soft HEAD~1

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


下面是一个示例:您在提交的开发服务器上做了一小部分工作。然后事实证明,该服务器没有传出 HTTPS 访问权限,因此您无法将提交推送到任何地方。最简单的方法就是假装它从未发生过,然后从本地机器上重做补丁。
@KarthikBose 总会有 reflog。即使在 git reset --hard HEAD~1 之后,您之前的最新提交也可以通过 reflog 获得(直到您过期);另见此处:gitready.com/intermediate/2009/02/09/…
谢谢。这个答案应该排名更高或包含在接受的答案中。删除提交!= 恢复提交。
@RandolphCarter:尽管如此,您仍然会丢失任何未提交的更改。
@Rob,一个例子是当你不小心提交了一个文件,其中包含一个永远不应该在源代码控制中的秘密(例如密码)。本地提交必须被销毁,而不仅仅是撤消,因此它永远不会被推送到服务器。
W
Will Ediger

删除整个提交

git rebase -p --onto SHA^ SHA

显然将“SHA”替换为您想要摆脱的参考。该命令中的“^”是文字。

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


-p, --preserve-merges 重新创建合并提交,而不是通过重放合并提交引入的提交来展平历史记录。不保留合并冲突解决方案或对合并提交的手动修改。
它说,“将 SHA 替换为您想要摆脱的参考”,但该行中有两次 SHA。这就是我所做的。 git rebase -p --onto 5ca8832c120^ 5ca8832c120 但没有任何改变。我应该使用相同的 SHA 两次吗?如果不是,那么哪个是要删除的提交的 SHA,另一个 SHA 应该是什么?
具体来说,此方法删除了整个提交,包括文件(在我的情况下不需要)
@Rubicksman ^ 必须在 Windows(cmd 窗口)上转义 (^^) - stackoverflow.com/questions/1955985/…
-p [DEPRECATED: use --rebase-merges instead]
t
tk_

假设我们要从 repo 中删除提交 2 和 4。 (提交的数字越大;0 是最旧的提交,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 推送到远程仓库。


最后一步应该是 git push -f origin master 没有选项 --hard
我猜 commit 0 早于 commit 1。请您告诉我为什么先运行 commit 3(通过樱桃挑选)然后运行 commit 1?结帐 b3d92cd (commit 0) 后,我希望挑选樱桃 commit 1,然后是 commit 3。谢谢。
@JarekC 我认为最重要的提交是这里的最新提交,除非我发现有问题...
这大部分是对的,但有点错误。我只是按照这个过程进行了一些调整。澄清:commit 0 是最新的提交,commit 4 是最旧的。首先检查 commit 5,就在您不想要的提交之前。然后是 cherry-pick commit 3,然后是 cherry-pick commit 1,然后是 commit 0。然后 checkout master 并将其重置为 commit 5 并按照其余步骤操作。
良好的彻底和安全的方法。在单独的分支上管理更改意味着您甚至可以在 repair 分支上进行交互式变基,并在合并回 master 之前合并提交。我唯一的评论是您可以合并前两个步骤:git checkout -b repair b3d92c5
J
Jakub Narębski

如果您没有发布更改,要删除最新提交,您可以这样做

$ git reset --hard HEAD^

(请注意,这也会删除所有未提交的更改;小心使用)。

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

$ git revert HEAD

那没有用。当我 git log 时,一切都还在那里,不管我为什么这样做只是增加了更多的提交。我要清理历史。
@Costa:什么不起作用(即您使用的是哪个版本),以及您是如何 git log 的?
我已经尝试了这个问答中的几乎所有内容。 (我最近尝试了 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:请注意,对于第一个版本(使用 git reset --hard HEAD^),您只能从当前分支“删除”提交(实际上是移动分支指针),如果有其他分支,则该提交仍然存在。使用 git reset “删除”提交只是将分支指针移回,使提交 dangling 并可用于修剪...如果其他 ref(其他分支、远程跟踪分支或标记)未引用。还是您使用了 git revert HEAD
我只想删除提交(就像它们从未存在过一样)。我开始了一些奇怪的编码冒险,有几个新的提交,最后都变成了垃圾。我怎样才能从我的 git 日志中删除那些?
Z
Zoe stands with Ukraine
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

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

您可以使用选项“d”或删除包含您的提交的行来简单地删除该提交。


在最新的 git 版本中,没有更多选项 d。您只需从 rebase 中删除带有提交的行即可删除它们。
C
Community
git reset --hard commitId

git push <origin> <branch> --force

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


git push --force 。因为没有提及分支名称,它可能会更改远程上的所有文件。
I
IliasT

强制更改历史记录

假设您不仅要删除最后一次提交,而且要删除最后 n 次提交的特定提交,请使用:

git rebase -i HEAD~<number of commits to go back>,如果您想查看最后五次提交,则为 git rebase -i HEAD~5

然后在文本编辑器中将您要删除的每个提交旁边的单词 pick 更改为 drop。保存并退出编辑器。瞧!

附加更改历史

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


drop 关键字未定义。要删除提交,只需删除整行。
对我来说 drop 被定义为一个关键字,但是做一个 drop 似乎并没有从历史中删除提交。但是,从交互式变基中删除了该行。
我按照几个地方的建议删除了该行:它没有做任何事情。用 drop 替换单词 pick 确实删除了提交。注意:说明在文本编辑器内容底部的注释部分中。使用 git version 2.24.3 (Apple Git-128)
J
Javier C.

[快速回答]

您有很多选择,例如:

备选方案 1: git rebase -i ~1 将 YourCommitId 更改为要恢复到的提交的编号。

备选方案 2: git reset --hard YourCommitId git push --force 将 YourCommitId 更改为您要恢复到的提交的编号。我不推荐此选项,因为您可能会丢失正在进行的工作。

备选方案 3: git reset --soft HEAD~1 您可以保留您的工作,只撤消提交。


git reset --soft HEAD~1 非常适合我。确保我不会因该提交而丢失更改。感谢您的明确答复。
A
Anurag-Sharma

如果您想修复最新的提交,您可以撤消提交,并取消暂存其中的文件,方法是:

git reset HEAD~1

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

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

git reset HEAD~N

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

git reset --hard HEAD~1

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

git reset --hard HEAD~N

我试过这个并且我删除了我的最新提交,但是现在当我推送到远程存储库时,它说我必须在推送之前拉取。所以我拉然后推,但是当我拉时,我再次得到了我刚刚删除的提交,因为我之前将它推到了远程。我现在该怎么办?
t
thestar

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

git reset --hard HEAD~1

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

git push origin HEAD --force

S
Sagar Jethi

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

删除最后一次提交

例如你的最后一次提交

git push origin +aa61ab32^:master

现在你想删除这个提交然后一个简单的方法来做到这一点

脚步

首先将分支重置为当前提交的父级 Force-push 到远程。

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

对于特定的提交,您要重置如下

git reset bb676878^ --hard

git push origin -f

F
Frank

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

Step1:使用 git log 获取提交 ID。

git log

https://i.stack.imgur.com/ndzyE.png

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

git reset --hard <your commit id>

S
Shog9

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

我认为没有办法通过 porcelain commands 删除提交。唯一的方法是将它从日志和引用日志中删除,然后执行 git prune --expire -now


StackOverflow 上显示答案的顺序不固定。请不要参考“以上所有命令”。使您自己的答案自成一体。
这个答案并不完全正确。 git prune is actually one of the "porcelain" commands。此外,您很少想要完全清除您的 reflog(一个用例是从您的存储库中删除敏感信息,但就像我说的那样,这是一个罕见的用例)。通常情况下,您会希望在 reflog 中保留旧的提交,以防您需要恢复数据。见Pro Git: 9.7 Git Internals - Maintenance and Data Recovery
C
CommaToast

这是另一种方法:

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

git reset --hard COMMIT_ID

由于您刚刚从远程签出您的分支,因此您无需担心丢失任何本地更改。但是,如果您这样做,这将失去它们。

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

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

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


P
Paulo Fidalgo

如果你想保留历史,显示提交和恢复,你应该使用:

git revert GIT_COMMIT_HASH

输入解释您为什么要恢复的消息,然后:

git push  

当您发出 git log 时,您将看到“错误”提交和恢复日志消息。


是的,但是 OP 很清楚这不是他们想要的。
L
Leo

错误:

git rebase -i --root编辑了我的分支,不知不觉地认为我可以改写与 master 不同的第一个提交(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> 有效后,我将另一个分支更新为 master 和 1... 2... 噗!提交又回来了——Git 赢了。

回到主人那里,是时候尝试 git rebase -i <SHA>,然后删除线......无济于事,遗憾的是。 “如果您在此处删除一行,COMMIT 将会丢失”。啊...在 2.8.3 release notes 中忽略了新功能 troll the n00b

解决方案:

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

为了验证,我检查了另一个分支,瞧 - 没有隐藏提交以从 master 获取/拉取。

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

祝你有美好的一天。


P
Pwnrar

如果您刚刚搞砸了上一次提交(错误消息,忘记添加一些更改)并且想要在将其推送到公共仓库之前修复它,为什么不使用:

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

如果您有新的暂存更改,它们将与最后一次提交(您试图摆脱的)合并,并将替换该提交。

当然,如果你在推送之后修改了一个提交,你就是在重写历史,所以如果你这样做了,一定要理解其中的含义。

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

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


这不是OP所要求的。
J
Justin

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

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

然后在每个已克隆 repo 的地方,运行:

git reset --hard origin/master

C
Chris Sim

当我提交和推送时,我通常会做什么(如果有人推送他的提交,这可以解决问题):

git reset --hard HEAD~1

git push -f origin

希望这有帮助


A
Ashish Singh

在本地分支上重置

git reset --hard HEAD~<Number of commit> So git reset --hard HEAD~3

强制推到原点

git push -f origin

S
Serg Burlaka

我已经推了。需要远程返回一些提交。尝试了许多变体,但只有 Justin 中的 this 通过 git bush 对我来说效果很好:

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

S
Shajed
// 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

参考:How to delete a commit in git, local and remote


J
Jyotirmoy Upadhaya

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


除非您已经推送了更改。在这种情况下,硬重置不会清理您的遥控器。在这种情况下,rebase 是不错的选择
L
Lava Sangeetham

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

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

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

git reset --soft HEAD^
git pull

S
Saurav Sahu

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

https://i.stack.imgur.com/qUdqU.png


这个问题不是关于intelliJ,而是关于Git 本身。
a
ankit

https://i.stack.imgur.com/ilul5.png

如上图所示,我想删除 revert"test change 2" 提交(SHA1 ID:015b5220c50e3dfbb1063f23789d92ae1d3481a2(您可以在 git bash 中使用 gitk 命令获取 SHA1 ID))。

为此我可以使用(以下所有命令仅在本地工作。您需要在删除后推送):

git reset --hard 515b5220c50e3dfbb1063f23789d92ae1d3481a2 //它支持你到那个提交(测试更改 4 提交的 SHA1 ID 是 515b5220c50e3dfbb1063f23789d92ae1d3481a2) git reset --hard HEAD~1 // 它在一次提交之前备份你。 git reset --hard HEAD^ // 从 git 中删除最后一次提交

删除后:

https://i.stack.imgur.com/aEPtg.png


B
BillChan

git reset --hard

git push origin HEAD --force

如果一个或多个提交被标记,请先删除标记。否则标记的提交不会被删除。