从git / GitHub的历史logging中删除文件夹及其内容
我在我的GitHub帐户上工作了一个存储库,这是我偶然发现的一个问题。
- Node.js项目与安装了几个npm软件包的文件夹
- 这些包在
node_modules
文件夹中 - 将该文件夹添加到git存储库,并将代码推送到github(当时没有考虑npm部分)
- 意识到你并不需要这个文件夹成为代码的一部分
- 删除该文件夹,推送它
在这种情况下,总的git回购的大小大约是6MB ,实际的代码(除了那个文件夹之外)只有大约300KB 。
现在我最终要找的是从git的历史中删除这个包文件夹的细节,所以如果有人克隆它,他们不必下载6mb的历史logging,只有他们将获得的实际文件截至上次提交将是300KB。
我查找了可能的解决scheme,并尝试了这两种方法
- 从git存储库中删除文件(历史logging)
- http://help.github.com/remove-sensitive-data/
- https://gist.github.com/1588371
Gist看起来好像是在脚本运行后的地方,它显示它已经删除了那个文件夹,然后显示出50个不同的提交被修改了。 但是它不让我推这个代码。 当我试图推动它时,它说Branch up to date
但是显示50个提交在git status
被修改。 其他两种方法也没有帮助。
现在,即使它显示它摆脱了该文件夹的历史logging,当我检查我的本地主机上的回购大小,它仍然是6MB左右。 (我也删除了refs/original
文件夹,但没有看到回购的大小的变化)。
我要澄清的是,如果有办法摆脱不仅提交历史(这是我认为发生的唯一的事情),而且还有那些git保持假设想要回滚的文件。
可以说一个解决scheme是为此提出的,并应用在我的本地主机,但不能被转载到该GitHub回购,是否有可能克隆回购,回滚到第一次提交执行的技巧和推它(或这是否意味着git会还有所有这些提交的历史? – 也就是6MB)。
我的最终目标是基本上find摆脱git的文件夹内容的最佳方式,以便用户不必下载6MB的东西,仍然可能有其他提交从未触摸模块文件夹(这很漂亮很多都是)git的历史。
我怎样才能做到这一点?
如果您在这里复制粘贴代码:
这是一个从历史中删除node_modules
的例子
git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d echo node_modules/ >> .gitignore git add .gitignore git commit -m 'Removing node_modules from git history' git gc git push origin master --force
我发现其他答案中使用的--tree-filter
选项可能会非常慢,特别是在大量提交大型库时。
这里是我使用的方法 – 使用--index-filter
选项从git历史logging中彻底删除一个目录,该选项运行速度更快:
# Make a fresh clone of YOUR_REPO git clone YOUR_REPO cd YOUR_REPO # Create tracking branches of all branches for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done # Remove DIRECTORY_NAME from all commits, then remove the refs to the old commits # (repeat these two commands for as many directories that you want to remove) git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch DIRECTORY_NAME/' --prune-empty --tag-name-filter cat -- --all git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d # Ensure all old refs are fully removed rm -Rf .git/logs .git/refs/original # Perform a garbage collection to remove commits with no refs git gc --prune=all --aggressive # Force push all branches to overwrite their history # (use with caution!) git push origin --all --force git push origin --tags --force
您可以使用以下命令检查gc
之前和之后的存储库大小:
git count-objects -vH
除了上面的stream行答案之外,我还想为Windows系统添加一些注释。 命令
git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD
-
完美的作品没有任何修改! 因此, 您不能使用
Remove-Item
,del
或其他任何内容而不是rm -rf
。 -
如果您需要指定文件或目录的path,请使用
./path/to/node_modules
类的./path/to/node_modules
我find的最好和最准确的方法是下载bfg.jar文件: https ://rtyley.github.io/bfg-repo-cleaner/
然后运行命令:
git clone --bare https://project/repository project-repository cd project-repository java -jar bfg.jar --delete-folders node_modules git reflog expire --expire=now --all && git gc --prune=now --aggressive git push --mirror https://project/new-repository
如果要删除文件,请使用delete-files选项:
java -jar bfg.jar --delete-files *.pyc
完成复制和粘贴配方,只需在注释中添加命令(对于复制粘贴解决scheme),在testing之后:
git filter-branch --tree-filter 'rm -rf node_modules' --prune-empty HEAD echo node_modules/ >> .gitignore git add .gitignore git commit -m 'Removing node_modules from git history' git gc git push origin master --force
在此之后,您可以从.gitignore中删除“node_modules /”行