Git@OSC禁止推送大于100M文件【…Q5】

2016/2/14 16:15:47

整理这篇笔记总共花费了差不多一个工作日的时间(8h),其他的笔记也很费事。所以我在思考一个问题,我整理笔记的方式是不是有问题?花费如此多的时间是否正常?

以上疑惑留待以后,下面进入正题。

问题描述与思考

这个标题可能不恰当,稍后修改。

起因是,前一阵子我开始把从网上找到的一些使用手册(chm格式)、电子书(pdf)等参考学习的资源放到版本控制的文档文件夹中,起初文件都不大,几百 KB,最大的不过 10M 左右,进行本地提交和远程推送都正常。直到,

大文件

这个逾百 M 文件的出现。本地提交正常,可是进行远程推送报错:

报错信息

报错给出的提示信息很明确,我使用的开源中国 OSC 的网站限制(暂时不打算更换其他的代码托管服务,更具体的说,目前 OSC 是最适合我的)100M 大小。

  1. 最开始我以为“git@oschina 网站不允许 single 文件大于 100M 的内容,所以把 C++ Primer 中文第 5 版使用 Adobe Acrobat 9 Pro 拆分后上传”,至于 200M+ 的大文件进行了“删除并添加到忽略列表”且“保留本地复本”,可是推送时依旧报错;
  2. 然后我以为“git@oschina 每次上传文件总和不能大于 100M,所以拆分后的 7 个子 pdf(一共 198M)分 3 次上传”,依旧报错。ps:通过在网上看到的一些介绍,以及回顾自己之前的使用经历,后者的猜测应该是错误的,毕竟若真是如此的话,那么在老东家时唐龙科技的整个几百兆的项目又是怎么推送的呢。

文件清单

至此,才开始认真考虑“265.pdf is 198.32 MB”这个信息,工作目录中肯定是没有这个文件,那么只能是 .git 隐藏目录了。发现 .git/objects 文件夹有将近 500M,肯定是有些太大了点,从网上搜到一条指令:(ps 通过《Pro Git 第2版》了解 git gc 这个命令,发现在这里使用根本就是驴唇不对马嘴)

1
2
#清理本地版本库
$ git gc --prune=now

执行完毕后,.git/objects 文件夹缩小到 273M。不过报错依旧。

进一步思考,发现自己还是没有认真思考错误提示,并且对 git 的工作方式的理解不够灵活。最终猜测,“虽然对文件(特指未拆分的大于 200M 的 pdf 文件)进行了删除操作且已再次提交过了,但是作为版本控制库,为了保证还原到上一版本,所以库中肯定是有文件的备份的”,若如此的话,合并新添此文件和删除此文件的两次提交(如果两次提并非相邻提交,则需要合并多个)即可解决问题。也不需要“规避小文件总体超标”(这个错误理解)。

合并前

合并,且放弃最新提交后

再次推送,成功!YES

推送成功

课后总结

Q1:最好找到开源中国对于代码服务推送文件大小限制的官方说明
——找不到,放弃。官方只有关于附件的一个说明,但目前我用不到“上传附件”的功能。

Q2:如果在新的提交上删除了之前提交的文件,库中肯定留有备份。但是如果已经 100% 确认肯定用不到了,那么这种备份如何从库中释放?除了上面合并两者(包含)之间所有的提交这种直接,但是却比较笨的方法,设想如果新添、删除两次提交不相邻,甚至有十几次、几十次提交了,还这么做肯定是不现实的。
——参考《Pro Git 第2版》中第7章 重写历史一节的 filter-branch 命令;参考 从git中永久删除文件以节省空间

Q3:如果是旧的提交中有,后来进行新提交时删除了(同上),而且添加到了 .gitignore 忽略文件,感觉应该自动从库中释放备份了呀,但事实上不会(例如上文中)。纠正此错误认知——考虑,其实 .gitignore 文件自身也可以是版本管理目标之一,也就是说如果还原到 A 提交,那么不单单 A、B 两次提交中间删除的文件的要还原,.gitignore 文件也要重置到 A 提交时未新添忽略项时的版本。.gitignore 文件忽略的项并不是时间轴上的全局,并不是一经修改,通吃过去和现在的。此文件只是针对提交的,并不是针对仓库的。
——在 D 盘进行试验,参考《Git 权威指南》第 7 章,使用 git reset 重置命令,注意其选项 --mixed--hard--soft

Q5:将学习材料、阅读材料使用云盘同步,因为这些文档不存在版本控制的问题;清理 OSC 版本库的提交
——迁移到了 onedrive 同步盘中。

.git文件过大,如何清理

强调一点,上面遇到的问题是代码托管服务平台的限制,所以我需要删除个别大文件,从所有有关提交中删除;.git 文件过大和前者完全是两个不同的问题,前者牵扯 git gc 操作完全是我个人理解上的错误。两者之间唯一的联系其实是“如何从每一个提交移除一个文件”,都使用 filter-branch 命令。

Q4:那么 .git 隐藏目录中的缓存、垃圾之类的是怎么来的?又该如何清理呢?

治标不治本

——这方面暂时不需要了解。如果觉得 clone 本地版本库时太大,可以指定深度,如下,为 1 即表示只克隆最近一次 commit。

1
git clone git://xxoo --depth 1

远程版本库,也可以先删除,然后完全重建版本库。前提是只要结果,过程已无任何价值。

1
2
3
4
5
6
$ rm -rf .git
$ git init
$ git add .
$ git cm "first commit"
$ git remote add origin <your_github_repo_url>
$ git push -f -u origin master

系统性的清理

以上只是治标不治本的方法,也有其使用限制。但是胜在快刀斩乱麻,不需要花费大量时间、精力去整理执行。系统性的清理参考以下:如何清洗 Git Repo 代码仓库。

知乎上看到一个答案,不知道合不合适,仅作参考:如何解决GitHub commit次数过多.git文件过大的问题

网络资源

后期在网上找到以下帖子,和我遇到的问题完全一致:处理GitHub不允许上传大于100M文件问题