如何从远程分支永久删除少量提交


489

我知道那是对历史的重写,是坏的矢田矢田。

但是,如何从远程分支中永久删除少量提交呢?


96
是的,这真的很糟糕yada yada,但是出于某种原因,我需要收藏它。
詹姆斯·莫里斯

44
我知道这很愚蠢,但有时会发生麻烦-例如测试登录并在代码中使用纯文本密码,它们是真实的登录凭据。
哎呀

6
真实的登录凭据..是的,让我想起了一些whopos
Hello Universe


2
我对这个学术上的尖语感到非常厌倦,因为这是多么危险以及永远不应该这样做。有时候从git历史中删除内容并处理其他开发人员的冲突/破坏要好得多。真的就是这么简单。忽视这一点的人可能从来没有在教室之外工作过。
暗恋

Answers:


368

您是git reset --hard您的本地分支,以便从工作树和索引中删除更改,并且您是git push --force将修改后的本地分支扩展到远程站点。(这里的其他解决方案,包括删除远程分支,然后重新按它)

这样的回答说明了执行此命令的危险,尤其是当人们依靠远程历史记录获取自己的本地存储库时。
您需要准备向人们指出手册页的“ 从UPSTREAM REBASE恢复”部分git rebase


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

那样可以恢复索引和工作树git reset --hard


奇怪。感觉就像我已经尝试过了。加上一些重新设置-就像一个魅力。谢谢。
阿尼斯·拉普萨

7
@Arnis:那就完美了;)push --force离开
VonC

我使用BFG Repo-Cleaner摆脱了一些敏感数据,这使我留下了一个带有原始文件的“未命名”分支,在重置为最后一个想要的提交并努力将其推送到原始位置后,一切都很好(:
Rodrirokr

请注意,提交的URL仍然有效(至少一段时间),因此,如果有人拥有提交的URL(您将其提供给上帝,知道原因),他们将可以访问代码。
Mosh Feu

1
@MoshFeu是:git gc并非总是在远程运行足够频繁。例如在GitHub:twitter.com/githubhelp/status/387926738161774592?
lang

248

请注意last_working_commit_id,在还原无效的提交时,请使用,

git reset --hard <last_working_commit_id>

因此,我们绝不能重置为 commit_id我们不想要的。

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

git push --force

10
完美,优雅,简单的答案。我刚刚恢复到在远程和本地都需要的最后一个stabe提交
lauWM

2
这也使我失去了本地更改。我没想到这一点。但是,比将您的个人密码提交工作回购要好。
Airwavezx

3
您可以使用git stash保存您的本地更改....做一些事情..和git stash pop(您的本地更改回来了)
MonTea '18

这给我带来的错误是“远程:错误:拒绝非快进裁判/裁判/大师(您应该先拉)”
Saurabhcdt

@Airwavezx git reset --hard应该执行的操作。
路加福音

146

要点:确保在“ git push -f”上指定哪个分支,否则可能会无意中修改其他分支![*]

本教程显示了三个选项。万一链接断开,我将在此处保留主要步骤。

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

1恢复完整的提交

git revert dd61ab23

2删除最后一次提交

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

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

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

其中+ dd61 ...是您的提交哈希,而git则将x ^解释为x的父级,而+则解释为强制的非fastforwared推送。

3从列表中删除提交

git rebase -i dd61ab23^

这将打开并显示所有提交列表的编辑器。删除您想要摆脱的那一个。完成变基并推动回购。

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

5
确保在“ git push <remote_repo> <remote_branch> -f”上指定哪个分支,否则可能会无意中修改其他分支!
Nigel Sheridan-Smith'4

仅第1步和第2步完成了工作并回答了原始问题。(不要执行第3步)
萨德·本布兹

这些是针对不同场景的选项,而不是要采取的步骤。就我而言,交互式变基(选项3)可以满足我的需求。
史蒂夫·布莱克威尔

不过,我必须执行第3步。为什么不运行此@Saad?幸运的是,我的<< remote >>只是默认的'origin',而<remote_branch>默认的'master'–
Bart

30

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

git reset --hard HEAD~3

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

git push --force

恭喜你!全做完了!

一些注意事项:

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

git log

然后你就可以代替HEAD~N使用<desired-commit-id>这样的:

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

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

重置索引,但不重置工作树(即,已更改的文件将保留,但未标记为提交),并报告尚未更新的内容。


10

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

最好在这里解释。


9
还不算太晚。对于类似问题的流浪者可能会很有用:)
Arnis Lapsa 2014年

9

同样基于此博客帖子,简化了pctroll的答案。

# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git 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

2
为我工作,谢谢。我想从远程分支历史记录中永久删除一个提交(例如包含pwd),这怎么办?
微笑

1
我也可以使用,但是我有一个与Smiles相同的问题,我不想让任何人在历史上看到我的承诺/崇高敬意。
罗伯托·罗德里格斯

4

有时,解决此问题的最简单方法是从您知道代码很好的地方创建一个新分支。然后,您可以不考虑错误的分支历史记录,以备日后需要从中提取其他提交时使用。这也可以确保您不会丢失任何提交历史记录。

从您当地的错误分支:

git log

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

git checkout theHashYouJustCopied
git checkout -b your_new_awesome_branch

现在,您将按照自己的方式创建一个新分支。

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

git checkout the_errant_branch
git log

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

git checkout your_new_awesome_branch
git cherry-pick theHashYouJustCopied

轻拍自己的背部。


非常容易,谁在乎您是否有分支机构?制作一个新的分支并完成它!
安德鲁·福克斯

这是一个非常好的答案。我很高兴能做到这一点,而不是选择无用的提交或操纵远程分支。
Magnilex

0
 git reset --soft commit_id
 git stash save "message"
 git reset --hard commit_id
 git stash apply stash stash@{0}
 git push --force
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.