Git LFS如何比Git更高效地追踪与存储二进制数据?
原问题
我了解Git LFS会让Git在文本文件中存储一个字符串“指针”,再由Git LFS下载目标二进制文件,这样远程Git服务器上的仓库体积更小。但Git LFS仍需存储二进制文件,我认为执行git lfs pull后的本地存储并无不同,远程Git服务器数据与Git LFS服务器数据的总和也相近。我忽略了什么?Git LFS是如何高效追踪二进制文件的?
更新(提问后深入学习所得):请勿使用git lfs,我现在不推荐使用git lfs
相关补充
- 我在已采纳回答下的评论
- 我刚添加的自答内容
- 我的《Git LFS很糟糕》吐槽:Git LFS速度慢、效率低、依赖在线环境(Git则支持离线),堪称“糟糕”。可在我的eRCaGuy_dotfiles仓库中查看完整吐槽。
我最初提出这个问题是因为我曾认为Git LFS很棒,想了解其原理。但最终我发现Git LFS是日常工作流问题的根源,不应再使用或推荐它。
总结
如我在某回答中所述:
对于个人免费GitHub账户,Git LFS的限制过于严苛;对于付费企业账户,它会让
git checkout从几秒延长至3小时以上,尤其对远程办公人员而言,完全是浪费时间。我受此困扰三年,苦不堪言。我曾写脚本每晚执行一次git lfs fetch来缓解问题,但雇主拒绝为我更换更大的SSD,导致我无法执行git lfs fetch --all,仍频繁遭遇数小时的checkout问题。此外,除非删除整个GitHub仓库并重新创建,否则无法撤销Git LFS与仓库的集成。
详情
我发现免费版git lfs的限制极为严格,几乎无用,目前我正从所有公共免费仓库中移除它。可查看关于GitHub仓库大小限制的回答并搜索“git lfs”相关内容。
在我看来,git lfs唯一的好处是克隆仓库时避免一次性下载大量数据而已!对于总内容大小(Git仓库+拟用Git LFS存储的内容)小于2TB左右的仓库,这个好处微乎其微,甚至无用。使用git lfs只会带来以下问题:
- 让
git checkout耗时极久(长达数小时) - 让原本快速离线的Git命令(如
git checkout)变成依赖在线的慢速命令 - 成为另一项需付费的GitHub服务
如果你像我一样,试图用git lfs规避GitHub的100MB单文件大小限制,千万别这么做!你会很快耗尽Git LFS存储空间,尤其是当有人克隆或复刻你的仓库时,流量会计入你的配额而非对方的!相反,可使用tar搭配split或单独使用split工具,将大文件分割为更小的部分(如每个90MB),再提交到常规Git仓库中。
最后,GitHub上停止使用git lfs并释放存储空间的“解决方案”简直离谱!你必须删除整个仓库!可查看相关问答:如何删除Git LFS追踪的文件并释放存储配额?
GitHub官方文档也证实了这一点(重点强调):
从Git LFS中移除文件后,Git LFS对象仍会保留在远程存储中,并继续占用你的Git LFS存储配额。
要从仓库中移除Git LFS对象,需删除并重新创建仓库。删除仓库时,所有关联的议题、星标和复刻也会被删除。
我无法相信这也能被称为“解决方案”,真心希望他们能推出更好的修复方案。
给考虑使用git lfs的雇主和企业的建议
简短总结
请勿使用git lfs,给员工配备更大的SSD即可。若最终仍决定使用git lfs,也请给员工配备更大的SSD,以便他们能在夜间运行脚本执行git lfs fetch --all。
详情
假设你是一家科技公司,拥有一个50GB的大型单体仓库,还有4TB需纳入仓库的二进制文件和数据。与其给员工配备500GB~2TB的小容量SSD,再依赖git lfs(会让远程办公人员在家庭网络下的git checkout从几秒延长至数小时),不如为员工配备更大的固态硬盘!一名技术员工的日均成本超过1000美元(每周5个工作日×每年48个工作周×1000美元/天=24万美元,这还低于薪资+福利+管理成本)。因此,一块1000美元的8TB SSD完全物有所值,能为员工节省大量等待时间,避免麻烦!推荐产品:
- 8TB Sabrent Rocket M.2 SSD,售价1100美元
- 8TB Inland M.2 SSD,售价900美元
这样员工就能有足够空间,通过自动化夜间脚本执行git lfs fetch --all来获取所有远程分支的LFS内容(缓解但无法解决问题),或至少执行git lfs fetch origin branch1 branch2 branch3来获取常用分支的内容。
另见
- 极具洞察力的问答,同样不推荐使用
git lfs(即使是远程仓库):本地仓库需要Git LFS吗? - Git LFS的优势是什么?
- 我的问答:
git checkout失败后如何恢复git lfs post-checkout钩子? - 我的回答:如何缩小Git仓库中的.git文件夹?
- 我的问答:
git lfs fetch、git lfs fetch --all与git lfs pull的区别是什么?
内容的提问来源于Stack Exchange,提问作者Gabriel Staples

