如何完全删除一个已合并的拉取请求?

3

我在GitHub上合并了一个Pull Request,但是这是个错误,我想撤销合并以及合并中的所有提交,并从历史记录中删除这几个提交引入的所有文件。

我使用另一个提交来回滚了原提交,但是这些文件仍然存在于提交历史记录中(它们很大),如果提交本身消失的话那就更好了。

我尝试了过滤分支并移除这些文件,但似乎没有缩小代码库的大小(而且提交仍然存在)。

我该怎么做?

5个回答

6

使用以下命令移除合并和提交:

git reset --hard <sha1>

如@knittl所描述的那样。但是,在您删除相关的悬空对象之前,您不会看到存储库大小的任何更改。您还需要过期reflog以保留对这些对象的引用,例如:

git reflog expire --expire-unreachable=now --all
git prune
git repack -a -d

2
使用tree-filter或index-filter没有起作用。硬重置和重新打包也不行。
以下是解决办法: git checkout <commit> git push --force origin HEAD:master 现在我很好奇为什么那些解决方案不起作用。我正在使用git count-objects -v中的size-pack进行检查。这样做正确吗?我应该立即看到尺寸减小还是只有在推送到origin后才能看到?

1

撤销提交不会从历史记录中删除文件。

如果你想让这些文件不仅在当前 HEAD 中不存在,而且在任何时候都不存在,那么 git revert 命令并不适合你。你需要运行一个 filter-branch 命令来完全删除这些文件。

你说你已经这样做了,但你没有向我们展示如何操作;如果你正确地执行以下步骤:

  • git filter-branch --tree-filter 来删除文件
  • git reflog expire --expire={1 second}
  • rm -rf .git/refs/original
  • git gc

...那么仓库应该会缩小。你需要进行最后三个步骤,因为(按顺序):

  • 原始提交可以通过你的 reflog 访问到
  • filter-branchrefs/original 中存储对原始提交的引用
  • 在运行垃圾回收之前,“松散”的对象不会被删除

我想删除一个文件夹。我尝试了: git filter-branch --tree-filter 'git rm -r --cached --ignore-unmatch badFolder'; git reflog expire --expire=now; rm -rf .git/refs/original; git gc; // 然后:git count-objects -v; 但是包的大小没有减小。 - Allan
@Allan 如果你正在使用 git rm 命令,那么你可能需要使用 git filter-branch --index-filter 而不是 git filter-branch --tree-filter - Borealid
1
@Borealid,你的解决方案仍有几个漏洞 - 使用“git reflog expire --expire = now --all”清除所有reflogs(每个分支都有一个reflog,并且可能仍然存在不同分支中的指针),而不是使用“git gc”,运行“git repack -Ad; git prune --expire = now”(git gc无法从现有的包文件中删除悬空对象,必须使用repack)。 - twalberg

1

如果您只想删除合并及其相关提交,请使用 git reset --hard 命令:

git reset --hard <commit before merge>

请注意,此操作将破坏您当前 HEAD 中的任何未提交更改。它还将删除合并之后发生的所有提交(因此,也许您最好使用 git rebase)。
重置分支后,请强制推送以使新的历史记录持久化。
免责声明:重新编写已经发布的历史记录是不好的做法。如果不必要,请不要这样做。

很遗憾,我必须:( - Allan

0

在我看来,最好的方法是使用Git Reflog:

git reflog

检查哪个点对你来说最好,然后移动到那里:

git reset --hard HEAD@{124}

然后,强制推送


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接