实际上,在 git 中删除提交是相当困难的,从设计上来说。人们的许多命令think删除提交(例如变基或重置),实际上只是使这些提交“无法访问” - 导致各种命令和工具的默认输出将它们排除在外。
删除提交的理由值得付出代价的情况相对较少。有时提交包含敏感信息(不过,在这种情况下,最好总是考虑信息受到损害,无论您是否努力将其从存储库中删除)。也许某个提交包含任何其他提交中都不存在的过大的二进制文件,从而使存储库膨胀。如果它只是归结为想要“隐藏”一个“错误”以使存储库看起来很完美,我不会在上面浪费时间。
但如果您确实想删除该提交,那么您需要了解以下内容:
首先,您必须删除提交的所有知识。你的reset
命令使其从您 ddi 的分支“无法访问”(通过父指针)reset
s。如果还有其他分支可以到达提交,则需要将它们reset
or rebased
远离提交(或删除)。如果已删除的提交上有标签,则需要移动或删除它们。在某些特殊情况下,其他参考文献可能指向提交,但我假设它们不适用。 (这将是诸如替换或来自的备份参考之类的事情filter-branch
...基本上,如果您可以在以下位置找到任一提交的 SHA.git/packed-refs
文件或以下任何文件中refs
,那么需要采取一些措施来解决这个问题。)
一旦所有引用被删除,提交就会“悬空”;但仍然可以通过 reflog 访问它。您可以尝试使 reflogs 过期
git reflog expire --expire=all --all
我在这方面从来没有什么运气(这可能只是意味着我从来不记得正确的论点);我总是最终做类似的事情
rm -r .git/logs
无论如何,缺点就是你会输all您的转发信息。您可以更有选择地选择要过期的重新记录。 (你可能需要HEAD
以及可以(或曾经)可以访问提交的任何分支。)您甚至可以使用delete
代替expire
寻找个别的重新记录条目。同样,这完全取决于您想为此付出多少努力。
因此,一旦没有引用和引用日志可以到达提交,gc
可用于从本地存储库中物理删除提交。
git gc --aggressive --prune=now
但现在仍然存在一个问题:如果提交被推送过,那么远程仍然有它们;现在推送不会将它们从远程删除。 (推送更新远程引用,并根据需要,adds填充历史的对象;但它不会从远程删除对象。)
如果远程只是文件共享(或您控制的 Web 服务器,或其他)上的存储库:您可以登录服务器并以与清理本地服务器相同的方式清理它。 (如果您已经推送了引用,那么该部分已经完成;但是您可能必须清理引用日志,并且必须运行gc
.)
如果远程是托管的(github、gitlab、TFS、bitbucket...),那么这取决于对哪些内容的访问gc
是楼主提供的。在 TFS 中(至少是我用过的版本),你就在树上;最好的情况是您可以删除并重新创建存储库。其他主机服务器可能提供触发的能力gc
,或者甚至可以运行gc
某些事件后自动进行;您必须查阅托管服务/软件的文档。