如何永久删除远程分支中的少数提交

我知道这是对历史的改写,这是糟糕的亚达亚达。

但是如何永久删除远程分支中的少数提交?

765514 次浏览

git reset --hard本地分支以从工作树和索引中删除更改,您git push --force(或git push --force-with-lease)修改后的本地分支到远程。
这里的其他解决方案,涉及删除远程分支,并重新推送)

这个所以回答说明了这种命令的危险性,特别是当人们依赖于远程历史记录来获取自己的本地存储库时。
你需要准备好向git rebase手册页的从上游恢复部分指出人员。

另外,正如的评论中的林戈所指出的,如果远程分支被保护免受强制推送,则git revert(如这个答案中)可能更可取。


在Git 2.23(九年后的2019年8月)中,您将使用新命令#0
即:git switch -C mybranch origin/mybranch~n
(将n替换为要删除的提交数)

这将恢复索引和工作树,就像git reset --hard一样。
留档添加

-C <new-branch>--force-create <new-branch>

--create类似,只是如果<new-branch>已经存在,它将被重置为<start-point>
这是一个方便的快捷方式:

$ git branch -f <new-branch>$ git switch <new-branch>

重要提示:确保您在“git ush-f”上指定了哪些分支,否则您可能会无意中修改其他分支![*]

本教程中显示了三个选项。如果链接中断,我将把主要步骤留在这里。

  1. 恢复完整提交
  2. 删除最后一次提交
  3. 从列表中删除提交

1恢复完整提交

git revert dd61ab23

2删除最后一次提交

git push <<remote>> +dd61ab23^:<<BRANCH_NAME_HERE>>

或者,如果分支在本地可用

git reset HEAD^ --hardgit push <<remote>> -f

其中+dd61…是您的提交哈希,git将x^解释为x的父级,并将+解释为强制非快速转发推送。

3从列表中删除提交

git rebase -i dd61ab23^

这将打开并编辑显示所有提交的列表。删除您要删除的那个。完成rebase并将force推送到repo。

git rebase --continuegit push <remote_repo> <remote_branch> -f

这可能为时已晚,但对我有帮助的是听起来很酷的“核”选项。基本上使用命令filter-branch,您可以在整个git历史记录中删除文件或更改大量文件。

这是最好的解释这里

从pctroll的答案简化,同样基于这个博客文章

# look up the commit id in git log or on github, e.g. 42480f3, then dogit checkout mastergit checkout your_branchgit revert 42480f3# a text editor will open, close it with ctrl+x (editor dependent)git push origin your_branch# or replace origin with your remote

有时解决此问题的最简单方法是从你知道代码良好的地方创建一个新分支。然后你可以单独留下错误的分支历史记录,以防以后需要从中挑选其他提交。这也确保你不会丢失任何提交历史记录。

来自您当地的errant分支:

git log

复制您希望分支所在的提交哈希并退出git日志

git checkout theHashYouJustCopiedgit checkout -b your_new_awesome_branch

现在你有了一个你想要的新分支。

如果您还需要保留不在新分支上的错误分支的特定提交,您可以选择您需要的特定提交:

git checkout the_errant_branchgit log

将您需要拉入good分支的一个提交的提交哈希复制并退出git日志。

git checkout your_new_awesome_branchgit cherry-pick theHashYouJustCopied

拍拍自己的背。

只需注意在恢复非工作提交时使用last_working_commit_id

git reset --hard <last_working_commit_id>

所以我们不能重置到我们不想要的commit_id

然后确定,我们必须推送到远程分支:

git push --force
 git reset --soft commit_idgit stash save "message"git reset --hard commit_idgit stash apply stash stash@{0}git push --force

如果您想删除例如最后3提交,请运行以下命令从文件系统(工作树)中删除更改并在本地分支上删除提交历史记录(索引):

git reset --hard HEAD~3

然后运行以下命令(在本地计算机上)强制远程分支重写其历史记录:

git push --force

恭喜!都搞定了!

一些备注:

您可以通过运行来检索所需的提交ID

git log

然后你可以像这样用<desired-commit-id>替换HEAD~N

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

如果您想在文件系统中保留更改并修改索引(提交历史记录),请使用--soft标志,如git reset --soft HEAD~3。然后您有机会检查您的最新更改并保留或删除全部或部分更改。在后一种情况下,runniggit status显示自<desired-commit-id>以来更改的文件。如果您使用--hard选项,git status会告诉您您的本地分支与远程分支完全相同。如果您不使用--hard也不使用--soft,则使用默认模式,即--mixed。在这种模式下,git help reset表示:

重置索引但不重置工作树(即,更改的文件是保存但未标记为提交)并报告未提交的内容更新中

TL:DR;

  1. git switch -C branch_name origin/branch_name~n
  2. git push --force

完成后,远程分支将由n提交恢复。


解释:

  1. 使用git switch,将分支重置n次提交。-C选项将强制创建一个同名的新分支。

    • branch_name替换为您的分支名称,
    • n(在命令末尾)替换为要恢复的提交数。

    命令#1:git switch -C branch_name origin/branch_name~n

    示例:git switch -C feature/dashboard origin/feature/dashboard~1//此命令恢复仪表板分支中的1提交。

  2. 强制推送本地更改

    命令#2:git push --force


提示:撤销已提交(未推送)的更改git reset HEAD~

我喜欢使用rebase。下面,n是最后n次提交。所以,如果你想删除第三个,请将n替换为3。

git rebase -i HEAD~n

然后,在清单中找到所需的提交并将其从“选择”更改为“删除”。退出rebase并使用带有“-f”选项的git ush,就像你刚刚做了一个rebase一样。