您可以应用的任何解决方案都将改写历史。这意味着它会对拥有你的 repo 副本的任何其他人产生不利影响,如果他们在尝试恢复时做错了事情,它可能会撤消你的修复。
因此,在公开可用的 repo 中出现这种情况是一个非常不幸的情况,但如果您碰巧知道没有多少人(或者可能没有人)克隆它,那么在实践中可能并不算太糟糕。重点是,以一种让所有回购用户都知道的方式传达你正在做的事情。
(通常我会说您需要任何拥有该回购副本的人的同意/协调;在这里,如果您将其视为您让其他人克隆的回购,我想您可以说只是衡量协调很好;但是除非您限制对源的推送,否则无论我们说什么“正确”,都存在某人进行“错误修复”并重新引入错误提交的可能性。)
无论如何,请注意以上内容,但实际上无济于事。你必须改写历史,问题是如何改写。
您可以删除自添加 node_modules 文件夹以来所做的所有提交,但当然您将丢失这些提交中的所有 other 更改。摆脱 node_modules 不丢失其他历史记录(并且没有 3rd 方工具)的最简单方法是 git filter-branch。
当然,您要确保在本地拥有所有参考。由于您的 repo 可能是您已复制到 github 的真正原始版本,因此应该没问题。但如果需要,您可以获取或什至对原点进行 --mirror 克隆以开始工作。那么
git filter-branch --index-filter 'git rm --cached --ignore-unmatch -r node_modules' -- --all
如果您的提交在node_modules 之外没有任何改变,并且想要丢弃这些提交,您可以在-- 分隔符之前添加--prune-empty 选项。
(在具有大量历史记录(许多提交)的 repo 上,这可能会很慢;在这种情况下,您可以考虑使用第三方工具,例如 BFG Repo Cleaner,它是用于删除大型/不需要的更专业的工具历史文件(与 filter-branch 相对,后者是一种更通用的工具)。
运行此程序并检查历史记录是否正常后,您将需要对本地存储库进行一些清理。可以说最简单的事情就是用它来创建一个新的克隆。
cd ..
git clone file://localhost/path/to/old/repo newrepo
如果您想清理原始本地存储库,则需要删除 filter-branch 创建的一组“备份引用”(在 refs/original 下),并可能清除引用日志,然后使用gc 实际扔掉不需要的对象。
至于 github 上的 repo,再次删除它并重新创建它可能是最简单的事情 - 特别是如果您有许多重写的分支。或者,您可以强制推送 (git push -f) 每个重写的分支,并查阅 github 文档以获取有关服务器端 gc 的信息