最近 git 改善了对浅克隆的支持
过去浅克隆就像 git 世界里的残障人士一样,某些操作并未得到支持。不过最近的版本 (1.9+) 对此有着显著的改善,现在甚至可以适当的对浅克隆库使用 pull 和 push 操作。
另一个解决办法是 filter-branch (过滤分支)
巨大的库往往存在着大量错误的提交或无用的资源,对此,使用 filter-branch 是个很好的解决办法。这个命令可以根据预先定义的模式对项目历史进行过滤、整理、修改,甚至跳过一些文件。它是 git 工具集中的一个非常强大的工具。目前已经有脚本可以用于识别 git 库中的大型对象,所以它使用起来非常容易。
使用 filter-branch 的示例:
git filter-branch --tree-filter 'rm -rf /path/to/spurious/asset/folder' HEAD
filter-branch 有一个小小的缺点:一旦使用了 filter-branch,实际上已经重写了整个项目历史,因此每次提交的 ID 都会发生变化。这要求每个开发者都要重新克隆更新后的库。
所以,如果你打算使用 filter-branch 来进行一次清理行动,应该警告你的团队,计划一个短期的冻结来进行操作,然后通知大家重新克隆库。
浅克隆的替代者:只克隆一个分支
从 2012 年 4 月发布的 git 1.7.10 开始,你可以通过只克隆某一个分支来限制历史记录的数量,就像这样:
git clone URL --branch branch_name --single-branch [folder]
对于长期运行分发的分支,或者你在有很多分支的情况下,这个特殊的技巧都非常有用。如果你只有极少数分支,那这个办法不会带来显著的效果。
处理拥有巨大二进制资产的库
第二类大型仓库中的代码含有巨大的二进制资产。游戏团队要处理巨大的 3D 模型,Web 开发团队需要跟踪图像资产,CAD 团队可能需要操作和跟踪二进制交付物的状态。所以有各种不同的软件团队在使用 git 的过程中会遇到这样的问题。
git 在处理二进制资产的时候并不是特别差劲,但它也不会干得特别好。默认情况下,git 会完整压缩存储二进制资产的所有后续版本,如果你有很多二进制资产的情况下,这显然不是最佳方案。
可以通过一些基本的调整来改善情况,比如运行垃圾回收 git gc,或者在 .gitattributes 中对部分二进制类型进行调整,以使用 delta 方式的提交。
不过有一点很重要,对项目中不同性质的二进制资产可能需要不同的方法。例如,这里需要检查三个方面(感谢 Stefan Saasen 的评论):
对于变化显著的二进制文件 - 这是指不仅只有元数据头变化 - 这时增量压缩可能没什么作用,建议对这些文件关闭 delta 选项,以避免不必要的增量压缩并重新打包
对于上述情形,就像某些文件通过 zlib 压缩并不会有多好的效果,你使用 core.compression 0 或 core.loosecompression 0 来关闭压缩功能一样;这是一个全局设置,它会对其它压缩效果不错的非二进制文件带来负面影响。因此建议你把二进制资产放在单独的库中。
一定要记住 git gc 将“重复的”松散的对象变成一个单独的包文件,除非以任何方式压缩文件都不会使生成的包文件有显著差异。
探索调整 core.bigFileThreshold 带来的效果。任何大于 512 MiB 都不会采用 delta 压缩 - 如果没有设置 .gitattributes 的话 - 所以这样的调整值得一试。
技巧1: 稀疏检出
一个温和的管理二进制资产问题的方法是稀疏检出(从 Git 1.7.0 之后可用)。我们可以通过显式地详细说明要填充的文件夹来保持工作目录的清洁。 不幸的是,它并不能影响整个本地存储库的大小,但如果你有一个巨大的树形文件夹,这可能是有用的。
涉及到哪些命令呢? 示例如下(credit):
仅克隆全部存储库一次::git clone <repository-address>
激活以下功能:git config core.sparsecheckout true
添加那些需要显式依赖的文件夹,忽略 assets 文件夹:
echo src/ ? .git/info/sparse-checkout
读取指定的树目录:git read-tree -m -u HEAD
之后,你可以使用正常的 git 命令了,但你的工作目录将只包含你指定的文件夹。
技巧2:使用子模块
还有另一种处理二进制资产目录的的方法,就是把它们拆分到一个单独的库,然后在主项目是通过把它拉取为子模块。使用这种方法你可以控制资产的更新。需要了解子模块,可以看看:核心概念与技巧和另一个选择。
如果你想继续使用子模块的方法,你可能需要检查项目依赖的复杂性。我提到的方法对解决大型二进制文件问题会有所帮助。
技巧3:使用 git-annex 或 git-bigfiles
git 中处理二进制资产的第3个选择依靠第三方扩展。
我要说的第一个扩展是 git-annex,它可以使用 git 管理二进制文件,但不需要把文件内容检入库中。git-annex 使用一个特殊的键值库来保存文件,然后将符号链接像普通文件一样检入 git 库中进行版本管理。这种用法非常直接,还有一看就能明白的例子。
第二个扩展是 git-bigfiles,一个 git 分支,适合于使用 git 分享项目大文件的人。
总结
不要因为你的库有着巨大的历史记录或巨大的资产就放弃 git。这两个问题都可以得到解决。