我知道 git LFS 导致 git在文本文件中存储一个字符串"指针",然后 git LFS 下载该目标二进制文件。这样,远程 git 服务器上的 git 存储库会更小。但是,git LFS 仍然必须存储二进制文件,所以在我看来,本地存储(git lfs pull
后)没有什么不同,远程 git LFS 服务器数据加上远程 git 数据的总和仍然相似。
我错过了什么?git LFS 如何有效地跟踪二进制文件?
更新(在写这个问题后经过额外的学习):不要使用git lfs
。我现在建议不要使用git lfs
另请参阅:
- 我在我接受的答案下方的评论
- 我自己的答案,我刚刚在下面添加
我从这个问题开始,因为我相信 Git LFS 是惊人的和美妙的,我想知道怎么做。相反,我最终意识到 Git LFS 是常工作流程问题的原因,我不应该再使用它或推荐它。
总结:
正如我在这里所说:
对于个人、免费的 GitHub 帐户来说,它的限制太大了,而对于付费的公司帐户,它使
git checkout
从几秒钟变成高达 3+小时,尤其是对于远程工作者来说,这完全是浪费他们的时间。我处理了三年,这太可怕了。我写了一个脚本,每晚做一次git lfs fetch
来缓解这种情况,但我的雇主拒绝给我买一个更大的 SSD,给我足够的空间让我每晚做一次git lfs fetch --all
,所以我仍然经常遇到几个小时结账的问题。除非删除整个 GitHub 存储库并从头开始重新创建它,否则也无法撤消将git lfs
集成到存储库中的集成。
详:
我刚刚发现git lfs
的免费版本有如此严格的限制,以至于它毫无用处,我现在正在将其从我所有的公共免费存储库中删除。请参阅此答案(GitHub.com 的存储库大小限制)并搜索"git lfs"部分。
在我看来,git lfs
的唯一好处是,当您克隆存储库时,它可以避免一次下载大量数据。就是这样!对于任何总内容大小(git repo + 可能的 git lfs 存储库)<2 TB 左右的存储库来说,这似乎是一个非常小的好处,如果不是无用的话。使用git lfs
所做的只是
- 让
git checkout
永远花几个小时(不好) - 使我通常快速和离线的 git 命令,就像现在
git checkout
变成在线和慢速 git 命令(坏),以及 - 充当另一个 GitHub 服务来支付(坏)。
如果您尝试使用git lfs
来克服 GitHub 的 100 MB 最大文件大小限制,就像我一样,请不要!您几乎会立即耗尽git lfs
空间,特别是如果有人克隆或分叉您的存储库,因为这会影响您的限制,而不是他们的限制!相反,"可以使用诸如tar
plussplit
之类的工具,或者单独split
,将大文件拆分为较小的部分,例如每个 90 MB"(源),以便您可以将这些二进制文件块提交到常规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
。
详:
假设您是一家科技公司,拥有大小为 50 GB 的庞大单存储库,以及您希望成为存储库一部分的二进制文件和数据,大小为 4 TB。与其给他们不足的 500 GB ~ 2 TB SSD,然后求助于git lfs
,这使得git checkout
在家庭互联网连接上完成时从几秒钟到几小时,不如让您的员工获得更大的固态硬盘!一个典型的技术员工的成本>1000 美元/天(每周 5 个工作日 x 48 个工作周/年 x 1000 美元/天 = 24 万美元,低于他们的工资 + 福利 + 间接费用)。因此,如果 1000 美元的 8 TB SSD 可以节省他们数小时的等待和麻烦,那么它是完全值得的!购买示例:
- 8TB 萨布伦特火箭 M.2 固态硬盘,1100 美元
- 8TB 内陆 M.2 固态硬盘,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
有什么区别?
克隆 Git 存储库时,必须下载其整个历史记录的压缩副本。 您可以访问每个文件的每个版本。
使用 Git LFS,文件数据不会存储在存储库中,因此当您克隆存储库时,它不必下载存储在 LFS 中的文件的完整历史记录。 仅从 LFS 服务器下载每个 LFS 文件的"当前"版本。 从技术上讲,LFS 文件是在"签出"而不是"克隆"期间下载的。
因此,Git LFS 与其说是有效地存储大文件,不如说是避免下载所选文件的不需要版本。 无论如何,该历史记录通常不是很有趣,如果您需要旧版本,Git 可以连接到 LFS 服务器并获取它。 这与常规 Git 形成对比,后者允许您离线签出任何提交。
git LFS 如何比 git 更有效地跟踪和存储二进制数据?
git LFS 如何有效地跟踪二进制文件?
总结
其实不然。它跟踪大型二进制文件的效率低下。它只是在单独的服务器上远程完成,以释放一些本地存储空间,并使初始git clone
过程最初下载的数据要少得多。这是它的要点:
@John 兹温克:
使用 Git LFS,文件数据不会存储在存储库中,因此当您克隆存储库时,它不必下载存储在 LFS 中的文件的完整历史记录。仅从 LFS 服务器下载每个 LFS 文件的"当前"版本。从技术上讲,LFS 文件是在"签出"而不是"克隆"期间下载的。
@Schwern:
- 它可以大大减少存储库的初始 git 克隆的大小。
- 它可以大大减少本地存储库的大小。
@Mark布拉姆尼克:
这个想法是二进制文件从"远程"存储库中懒惰地下载,即在签出过程中而不是在克隆或获取过程中。
详
常规 Git 存储库
假设你有一个庞大的单存储库,其中包含大约 100 GB 的文本文件(代码,包括所有 git blob 和更改)和 100 GB 的二进制数据。请注意,这是一个现实的、有代表性的例子,我实际上处理了几年。如果 100 GB 的二进制数据已提交一次,则占用 100 GB,而总 git 存储库为 100 GB 的代码 blob + 提交一次的 100 GB 二进制数据 = 200 GB。
但是,如果每个文件的 100 GB 二进制数据已更改 10 次,则它占用 ~100 GB x (1 + 10) = 1.1 TB 的空间,+ 100 GB 代码 -->1.2 TB存储库大小。现在,克隆此存储库:
# this downloads 1.2 TB of data
git clone git@github.com:MyUsername/MyRepo.github.io.git
如果你想做一个git checkout
,但它很快!所有二进制数据都存储在本地存储库中,因为您拥有二进制数据的所有 11 个快照(初始文件 + 10 个更改)!
# this downloads 0 bytes of data;
# takes **seconds**; you already have the binary data locally, so no new data is
# downloaded from the remote server
git checkout some_past_commit
# this takes seconds and downloads 0 bytes of new data as well
git checkout another_past_commit
与此形成对比git lfs
:
LFS 进行所有二进制文件存储的 Git 存储库
您的存储库与上述相同,只是 git 存储库中只有 100 GB 的代码。Git LFS 导致 git 只将指针文本文件存储到 LFS 服务器,因此 git 存储库中的内容只是 100 GB 的代码 + 指针文件的一点点存储。
另一方面,Git LFS 服务器包含所有1.1 TB 的二进制文件。所以,你会得到这个效果:
# this downloads 0.1 TB (100 GB) of code/text data
git clone git@github.com:MyUsername/my_repo.github.io.git
# this downloads 0.1 TB (100 GB) of binary data--just the most-recent snapshot
# of all 100 GB of binary data on Git LFS
cd my_repo
git lfs pull
# this downloads potentially up to another 0.1 TB (100 GB) of data;
# takes **hours**; you do NOT have the binary data for all snapshots stored
# locally, so at **checkout** Git LFS causes your system to download all new
# LFS data!
git checkout some_past_commit
# this downloads up to another 0.1 TB (100 GB) of data, taking **more hours**
git checkout another_past_commit
实际上,常规 Git 存储二进制 blob 的效率高于 Git LFS
请参阅@Alexander Gogl的回答中的表格 这里.添加 28.8 MB 的 Vectorworks (.vwx) 文件需要 26.5 MB 作为 git blob,26.5 MB 作为 Git LFS blob。但是,如果将其存储为 git blob,然后运行git gc
来执行"垃圾回收"和 blob 压缩,则常规 git 会将其缩小到 1.8 MB。Git LFS 不会对它做任何事情。另请参阅此表中的其他示例。
如果你看一下这个表,你会发现 git 整体存储比 Git LFS 更有效率:
type change file as git blob After git gc
as git-lfsblob td style="文本对齐:右;">28,8 MB Vectorworks (.vwx) 添加了几何 <+26,5 MB +1,8 MB +26,5 MB td style="文本对齐:右;">16,9 MB GeoPackage (.gpkg) 添加了几何 <+3,7 MB +3,5 MB +16,9 MB style="文本对齐:右;">85,8 MB 亲和力照片 (.afphoto) 切换图层 +85,6 MB +0,8 MB +85,6 MB td style="文本对齐:右;">66,3 MB FormZ (.fmz) 添加了 几何<+66,3 MB +66,3 MB +66,3 MB td style="text-align: right;">25,8 MB Photoshop (.psd) 切换图层 <+15,8 MB +15,4 MB +25,8 MB style="文本对齐:右;">13,1 MB 影片 (mp4) 修剪< td+13,2 MB +0 MB +13,1 MB style="文本对齐:右;">-13,1 MB 删除文件 +0 MB +0 MB +0 MB
相关内容
- 使用 git-filter-repo --subdirectory-filter 后更新 git 存储库
- 如何签出(下载)git存储库目录内的单个文件
- 使用自定义命令行选项从git存储库为特定分支创建tar文件
- git 存储库已损坏,无法达到以下状态:"BUG: fsmonitor.c:21: fsmonitor_dirty has more entries than the index"
- 从源代码构建GNU make.GIT存储库中丢失的文件
- 在克隆git存储库之前忘记分叉
- 在 Docker 中使用 Gitlab-Runner 在本地测试构建管道。错误:"文件夹"似乎不是 git 存储库
- 如何检查公共git存储库是否更新?
- 从缺少 setup.py 文件的 git 存储库导入库
- 'go get'不适用于我自己的 git 存储库
- 你怎么安装R包从一个私人git存储库帕特?
- 如何修改 Git 存储库以使其更"branchy"应有的状态?
- 无法使用SSH克隆GIT存储库
- 与 2019 年相比,更改 GIT 存储库时出现错误"Microsoft.TeamFoundation.Git.Contract.GitCheckOutConflictException"
- 如何在没有提交历史的git存储库中恢复强制删除的文件?
- 可以克隆我的 Git 存储库,但无法提交和推送
- 如何设置git存储库以忽略以前的所有提交并从新的初始提交开始
- 更新 Git 存储库/Github 中的文件,并且不跟踪更改或删除以前的提交
- < h1 >是测量的时间在一个git存储库的代码吗?
- 构建Git存储库的良好实践
最新更新
- 在Swift中从实时数据库Firebase中获取数据
- Devstack单一接口不能在ubuntu 20.04上工作
- Typescript没有安装
- 函数式语言类型推断混乱
- 使用Python从大文件解析数字数据时提高速度
- 如何从Multipass共享文件夹到主机?
- 从CMD或批处理文件中禁用"Notify me when the clock changes"设置
- 在Dockerfile中设置——net=host ?
- 如何在React中将arrayBuffer转换为JSON
- 是否有可能将html响应转换为json在扑动?
- 快速过滤numpy数组值的方法
- C保存字符串的数组列表
- 需要minio film配置建议
- 如何应用CSS字体大小"relative to what it would be originally"?
- 该应用程序在个人帐户中未绑定脚本时被阻止错误
- 将原始查询转换为django orm
- 如何从出现次数和值的列表中创建一个新列表
- 使用Julia中的Julia Broadcasting根据数组的索引计算数组值
- 在javascript中使用条件更新嵌套数组
- for循环多个条件
- 将第一列中的名称行转换为r中的列
- Nx张量的映射切片
- Dotnet Core Azure功能(隔离进程)如何加载应用程序.每个环境的Json
- Discordjs不发送消息
- 边框在css中不显示
- Python pandas中的深度嵌套JSON规范化
- 如何在JSON模式中从正确的对象中选择特定的字段
- 我可以在REST API中直接通过POST发送电话号码吗?
- "onPressed: () {}"在颤振中不起作用
- FbLitho在RecyclerCollectionComponent中重复视图,即使加载了新部分
热门标签:
javascript python java c# php android html jquery c++ css ios sql mysql arrays asp.net json python-3.x ruby-on-rails .net sql-server django objective-c excel regex ruby linux ajax iphone xml vba spring asp.net-mvc database wordpress string postgresql wpf windows xcode bash git oracle list vb.net multithreading eclipse algorithm macos powershell visual-studio image forms numpy scala function api selenium