【发布时间】:2012-12-25 05:47:55
【问题描述】:
我在 GitHub 上合并了一个拉取请求。然而,这是一个错误,我想撤消合并,它的提交,最重要的是,从历史记录中删除这几个提交引入的所有文件。
我用另一个恢复提交并且它可以工作,但文件仍在提交历史记录中(它们很大),如果提交本身消失会很好。
我尝试过滤分支删除文件,但它似乎并没有缩小存储库大小(并且提交仍然存在)。
我该怎么办?
【问题讨论】:
标签: git github merge pull-request
我在 GitHub 上合并了一个拉取请求。然而,这是一个错误,我想撤消合并,它的提交,最重要的是,从历史记录中删除这几个提交引入的所有文件。
我用另一个恢复提交并且它可以工作,但文件仍在提交历史记录中(它们很大),如果提交本身消失会很好。
我尝试过滤分支删除文件,但它似乎并没有缩小存储库大小(并且提交仍然存在)。
我该怎么办?
【问题讨论】:
标签: git github merge pull-request
恢复提交不会从历史记录中删除文件。
如果您希望文件不仅不存在于当前 HEAD 中,而且根本不存在,git revert 不适合您。您需要运行 filter-branch 才能完全删除这些文件。
你说你已经做到了,但你没有告诉我们怎么做;如果您正确地执行了以下操作:
git filter-branch --tree-filter 删除文件git reflog expire --expire={1 second}rm -rf .git/refs/originalgit gc... then 存储库应该缩小。您需要最后三个步骤,因为(按顺序):
filter-branch 存储在refs/original 中
【讨论】:
git rm 命令,您可能需要git filter-branch --index-filter 而不是git filter-branch --tree-filter。
git reflog expire --expire=now --all 清理所有 reflog(每个分支都有一个 reflog,并且可能仍然有不同分支中的指针),而不是 git gc ,运行git repack -Ad; git prune --expire=now(git gc 不会从现有包文件中删除悬空对象,repack 是必需的)。
如果您只想删除合并及其关联的提交,请使用git reset --hard:
git reset --hard <commit before merge>
请注意,这将破坏您当前 HEAD 中任何未提交的更改。它还将删除合并后发生的所有提交(所以也许你最好使用 git rebase)。
重置您的分支后,强制推送它以使新历史持久化。
免责声明:重写已发布的历史记录是不好的做法。如果没有必要,请不要这样做。
【讨论】:
删除合并和提交
git reset --hard <sha1>
如@knittl 所述。但是,在删除关联的悬空对象之前,您不会看到存储库大小的任何变化。您还需要使 reflog 不再保留对这些对象的引用,例如
git reflog expire --expire-unreachable=now --all
git prune
git repack -a -d
【讨论】:
使用树过滤器或索引过滤器不起作用。硬重置和重新包装也没有。
以下是有效的:
git checkout <commit>
git push --force origin HEAD:master
现在我很好奇为什么这些解决方案不起作用。我正在使用git count-objects -v 中的尺寸包进行检查。它是否正确?我应该立即看到尺寸减小还是仅在推到原点后才看到尺寸减小?
【讨论】: