How I Use Git LFS to Manage Large Git Files?

我如何使用 Git LFS 来管理大型 Git 档案?

前言

Git 是一款强大的版本控制系统,可以记录任何文件的更改,并且可以轻松地回溯到任何一个版本。然而,当需要存储大型文件时,Git 就显得力不从心,因为 Git 并不是为了存储大型文件(图片、视频、音乐……等二进制文件)而设计的

试想一张 1MB 的图片只要修改了 10 次,Git 就会将这 10 个版本的图片都存储到仓库中,也就是占用了 10MB 的空间!(虽然这样简单的说明并不完全准确,实际上 Git 会存储两个版本之间的差异,而不是存储每个版本的完整副本,但二进制文件的差异难以压缩仍然是一个挑战)。这种情况会导致性能下降、浪费存储空间、消耗网络资源等问题。而本次介绍的 Git Large File Storage(Git LFS)是一种 Git 的扩展,专门用来解决上述问题。

Git LFS 如何解决问题?

Git LFS 解决问题的方式是将大型文件内容存储在额外的服务器上,而不是直接存储在 Git 仓库中。通过将实际的大型文件替换为指向该文件的指针,即使文件再大、修改次数再多,Git 仓库的大小都不会增加。

除了存储得到了优化,同步大型文件到本地也更加方便。相比于下载整个 Git 仓库的历史记录,使用 LFS 时,我们可以选择只下载当前所需的大型文件,从而节省资源。

如何使用 Git LFS?

一、下载 Git LFS

首先需要安装 Git LFS (废话 😐)

Terminal window
git lfs install

二、设定要使用 Git LFS 的档案

在需要使用 Git LFS 的 Git 仓库中,可以选择希望 Git LFS 管理的文件类型(或者直接编辑 .gitattributes 文件)。您可以随时配置新的文件扩展名以让 LFS 介入处理。以下设置指定了 LFS 需要处理所有 .png 扩展名的文件:

Terminal window
git lfs track "*.png"

设定完成后须确保 .gitattributes 的更动有被提交到 Git 储存库中。

三、提交档案

Terminal window
git add foobar.png
git commit -m "Add foobar.png"
git push origin main

如果你和我一样使用 GitHub 来托管代码,只需像平常一样提交文件即可,GitHub 会为你处理好后续的事情 🤯。在 GitHub 上预览 LFS 文件时会有相应的标注,除此之外,使用体验与没有使用 LFS 时完全一致。

GitHub LFS

如果想列出当前被 LFS 管理的文件,可以执行以下命令进行查看:

Terminal window
git lfs ls-files

会得到详尽的 LFS 管理档案清单如下:

071ba8a6fd * fonts/NotoSansTC-Bold.ttf
6b137e2eb5 * fonts/NotoSansTC-Regular.ttf
ba2e34dddb * public/images/brand/default-og.jpg
0866a98641 * public/images/brand/favicon/apple-touch-icon.png
c58814f7fa * public/images/brand/favicon/icon-192

使用 Git LFS 后的体验

目前整个网页东东大型文件都是通过 GitHub LFS 托管的,大幅简化了我的工作流程与提高效率。

早期这个网站建置时会需要设置额外的 CMS 服务器,或是使用 Cloudinary 这类第三方资产托管服务才能把图片带入文章中,但现在只要把图片放到 Git 存储库中就能直接使用,对网页东东这个单纯由开发者来经营的网站来说是优雅精简的流程(GitHub 就像是我的 Git-Based CMS)。

就算你的网站不是由开发者经营,仍可以通过 Git LFS 来管理大型文件,像是些许的 Open Graph 图片、字体文件……把资源都集中管理在同个地方也是非常方便。

使用 Git LFS 须注意的事项

Git LFS 服务不是无限免费的

可以查看 bill for Git Large File Storage🔗 以及 Viewing your Git Large File Storage usage🔗 或提供 LFS 的厂商服务价格细节了解更多。

就网页东东整个博客为例,大大小小的视频、图片、字体……至今共 251 个 LFS 文件也才使用了 43.2 MB 的空间额度,当然也是因为有多事先留意并压缩这些文件,但必须说每个月 1 GB 免费额度已经足够很多情境免费用到烂了。

GitHub LFS 使用额度
网页东东博客 Git LFS 存储使用额度

CI/CD 流程上须留意

GitHub LFS 流量使用额度
网页东东博客 Git LFS 流量使用额度

因为 Git LFS 会将大型文件储存在额外的服务器上,所以在 CI/CD 流程上会需要额外的设置来下载这些 LFS 文件,这点在我的博客中也有实践🔗,并且还有额外设置缓存来避免重复的获取相同的 LFS 文件🔗

总结

会写这篇文章也是因为先前团队并没有导入 Git LFS 的习惯,一些大型的网页资产仍是直接储存在 Git 存储库当中,随着架构更新以及导入 Monorepo 的架构,可以预期项目大小会直线升高,也促使我希望能够在初期就导入 Git LFS 来预防 Git 存储库炸裂的问题。

我认为这项技术特别适合在某些领域中使用,像是:前端或游戏开发这类需要与大量二进制文件互动的领域。

延伸阅读