如果你长期使用 Obsidian + Git 方案时,你可能会遇到一个问题。在新设备上很难完成首次 clone 操作。
有一个原因是因为你的仓库过大了,比如包含了太多图片文件,这会导致首次拉取困难或超时的问题,非常棘手。
但其实在 Git 领域,早已有办法可以解决,那就是利用 Git LFS 功能,Git Large File Storage(LFS)提供了一个高效的解决方案,对图片进行特殊存储,而不进行变更追踪。
这样做的好处是,在拉取时能够区分文本文件和 LFS 文件,能够显著减少 git 仓库本身的大小,使仓库能够容纳更多文本文件,同时在 Git 体验上保持一致。相比使用在线图床,你不需要担心图床哪一天挂了导致丢失数据和迁移困难。
所以本文就来介绍如何为一个已有的 Obsidian 仓库启用 Git LFS 功能。
准备工作
在开始本文前,你需要先为 Obsidian 仓库配置 Git。你可以先参考以下两篇文章,包括 Git 的安装、仓库的 clone 和其他基础配置,然后再继续后面的步骤。
正确启用 Git LFS 没有风险,但仍然有可能因输错指令、误操作、难以解决与远端的冲突、网络等原因导致仓库出现各种 Git 相关的问题,这些问题通常可以搜索到较为明确的解决办法。如果对自己的 Git 知识没有信心,建议在进行任何操作前对仓库进行全量备份。
可选步骤:我建议在桌面端安装 VSCode 客户端,在其中打开 Obsidian 仓库的目录,并 VSCode 的终端中完成接下来的命令行操作。这样你可以在 Git 页面清楚地看到每一步操作的结果,判断命令是否生效。
如何为一个已有仓库启用 Git LFS
如果你已经完成了准备工作,那接下来的工作应该不成问题。如果出现任何报错,建议立即停止并上网搜索相应报错的解决方法,我在文末也会附上一些错误的解决方法。
- 首先,你需要在本机电脑上安装 Git LFS。在命令行中运行以下命令:
git lfs install
- 然后,你需要选择哪些文件类型需要使用 LFS 来跟踪。例如,如果你想跟踪所有的 .jpg 和 .png 图像文件,你可以运行以下命令:
git lfs track "*.jpg" git lfs track "*.png"
这会在你的仓库中创建一个名为.gitattributes
的文件,其中包含了哪些文件类型被 Git LFS 跟踪的信息。 - 将
.gitattributes
文件添加到 Git 仓库并提交:git add .gitattributes git commit -m "Add Git LFS for *.jpg and *.png files"
- 现在,你可以像平常一样添加、提交和推送你的文件。当你添加和提交一个被 Git LFS 跟踪的文件时,实际存储在 Git 仓库中的只是一个指向 LFS 存储的文件的指针,而不是文件本身。
git add file.jpg git commit -m "Add large file" git push origin master
注意:Git LFS 需要在每台机器上单独安装和设置。如果你在一个新的机器上克隆了一个使用了 Git LFS 的仓库,你需要在那台机器上运行 git lfs install
。
此外,Git LFS 需要在服务器端的支持。GitHub、GitLab 和 Bitbucket 都支持 Git LFS,但是如果你使用的是自定义的 Git 服务器,你可能需要检查它是否支持 Git LFS。
如何避免拉取附件
启用了 Git LFS 后,你会发现克隆仓库时仍然会全量克隆,并没有减小仓库的尺寸。但是速度似乎变快了一些,这是因为 Git LFS 默认情况下是将文件进行区分,并且在拉取文件时做了一些优化,比如先完成 clone 内容后,再批量下载 LFS 文件,这会提高一些性能。
如果你想只拉取 Git 仓库中的内容而暂不拉取 Git LFS 管理的文件,你可以使用以下几种方法:
方法 1: 使用 git clone
的 --filter=blob:none
选项
Git 提供了一种部分克隆的方式,可以在克隆时不拉取任何大文件(包括 Git LFS 管理的文件),只拉取指针文件。这个方法只适用于 Git 2.19 及以上版本。1
git clone --filter=blob:none <repository-url>
使用这个命令克隆仓库时,只会下载 Git 的内容,而不会下载 LFS 文件。当你需要特定的 LFS 文件时,可以通过 git lfs pull
手动拉取。
这样一来,加速效果会非常显著(毕竟需要下载的文件数量大大减少了)。根据这篇文档中的测试数据——
例如,linux 的内核,目前有 100 万以上的提交,整个仓库包含了 830 万 + 的对象,体积约在 3.3GB 左右。要全量克隆这样一个仓库,克隆速度以 2MB/s 来算,需要约 26 分钟的时间。在网络条件不佳的情况下,克隆可能还会耗费更久的时间。
使用了 blob:none 选项后,需要下载的对象由 834 万左右减少至 602 万左右,需要下载的数据量更是由 3.26GB 下降到了 1.13GB,还是以 2MB/s 速度来计算,部分克隆时间仅需 9 分钟左右,与原来的全量克隆相比,时间仅为原来的三分之一左右。
而 Obsidian 中排除掉附件的话,文本文件的量也绝不会像 Linux 内核这么夸张,因此可以大大减少内容同步的时间。
方法 2: 禁用自动下载 LFS 文件
如果你已经克隆了仓库,可以通过禁用 LFS 自动下载的方式,只拉取 Git 的内容。
- 禁用自动下载:
git lfs install --skip-smudge
--skip-smudge
选项会禁用在git pull
或git checkout
时自动下载 LFS 文件。 - 现在你可以正常拉取仓库内容,但 LFS 文件将不会被下载。仓库中的 LFS 文件会显示为指针文件。
- 当你需要下载特定的 LFS 文件时,可以使用:
git lfs pull
或者使用以下命令下载特定目录或文件的 LFS 文件:git lfs pull -I "path/to/your/file/or/folder"
这样一来,你可以让仓库在你寸土寸金的小容量电脑中,保持一个较小的尺寸的同时,也能正常使用。
如何解决疑难杂症
在启用 LFS 后出现许多报错
在正确启用 Git FLS 后,你可能需要完整重新 git clone 整个仓库。而不是在原有仓库的基础上进行 git pull(如果你没有正确处理冲突文件,有概率出现大量冲突报错,而重新 clone 是最简单的方法)。
需要确认客户端、服务端都支持 Git LFS
我在 Obsidian 的 PC 端同步方案,无代码搞定 Git 同步 一文中提到,我使用本地部署的 gogs 作为服务端。本地部署的 gogs 尽管支持 LFS 功能,但是由于在开启两步验证后,需要改用个人令牌的登陆方式。在电脑端的 git-lfs 功能全面,不会遇到问题。
而手机端的 Working Copy 并不能完全兼容 gogs 将 token 作为用户名的登陆方式,因此在手机端在 push 带有 LFS 的 gogs 仓库时,会遇到反复提示“需要授权”的问题。导致最终无论是将 token 作为用户名还是作为密码,都无法完成同步。
解决方法是关闭两步验证、不要使用 LFS、或将自己部署的 Gogs 改为 Working Copy 支持较好且与 Gogs 类似的 Gitea。我选择的方法就是改用 Gitea 后端,将 Gogs 的数据都迁移过来。
Github + token 授权没有此问题。
小结
Git LFS 方案算是 Git 提供的一个减小仓库同步大小的方案,它没有实质性地解决 Obsidian 仓库过大的问题,而是区分文件的类型,在“同步”速度上下功夫。在“小容量设备部分同步仓库”的场景下,是一个很好的处理方案。