# 如何使用 Git LFS 功能解决 Obsidian 过多附件导致的首次同步问题

> 本文公开全文。

原文：https://utgd.net/article/20870

如果你长期使用 Obsidian \+ Git 方案时，你可能会遇到一个问题。在新设备上很难完成首次 clone 操作。

有一个原因是因为你的仓库过大了，比如包含了太多图片文件，这会导致首次拉取困难或超时的问题，非常棘手。

但其实在 Git 领域，早已有办法可以解决，那就是利用 Git LFS 功能，Git Large File Storage（LFS）提供了一个高效的解决方案，对图片进行特殊存储，而不进行变更追踪。

这样做的好处是，在拉取时能够区分文本文件和 LFS 文件，能够显著减少 git 仓库本身的大小，使仓库能够容纳更多文本文件，同时在 Git 体验上保持一致。相比使用在线图床，你不需要担心图床哪一天挂了导致丢失数据和迁移困难。

所以本文就来介绍如何为一个已有的 Obsidian 仓库启用 Git LFS 功能。

## 准备工作

在开始本文前，你需要先为 Obsidian 仓库配置 Git。你可以先参考以下两篇文章，包括 Git 的安装、仓库的 clone 和其他基础配置，然后再继续后面的步骤。

- 《Obsidian 的 PC 端同步方案，无代码搞定 Git 同步》

- 《Obsidian 的手机端同步方案，iOS \+ Git \+ Shortcuts 实现自动同步》

正确启用 Git LFS 没有风险，但仍然有可能因输错指令、误操作、难以解决与远端的冲突、网络等原因导致仓库出现各种 Git 相关的问题，这些问题通常可以搜索到较为明确的解决办法。如果对自己的 Git 知识没有信心，建议在进行任何操作前对仓库进行全量备份。

可选步骤：我建议在桌面端安装 VSCode 客户端，在其中打开 Obsidian 仓库的目录，并 VSCode 的终端中完成接下来的命令行操作。这样你可以在 Git 页面清楚地看到每一步操作的结果，判断命令是否生效。

## 如何为一个已有仓库启用 Git LFS

如果你已经完成了准备工作，那接下来的工作应该不成问题。如果出现任何报错，建议立即停止并上网搜索相应报错的解决方法，我在文末也会附上一些错误的解决方法。

- 首先，你需要在本机电脑上安装 Git LFS。在命令行中运行以下命令：

bash git lfs install

- 然后，你需要选择哪些文件类型需要使用 LFS 来跟踪。例如，如果你想跟踪所有的 \.jpg 和 \.png 图像文件，你可以运行以下命令：

bash git lfs track "\*\.jpg" git lfs track "\*\.png"

这会在你的仓库中创建一个名为 \.gitattributes 的文件，其中包含了哪些文件类型被 Git LFS 跟踪的信息。

- 将 \.gitattributes 文件添加到 Git 仓库并提交：

bash git add \.gitattributes git commit \-m "Add Git LFS for \*\.jpg and \*\.png files"

- 现在，你可以像平常一样添加、提交和推送你的文件。当你添加和提交一个被 Git LFS 跟踪的文件时，实际存储在 Git 仓库中的只是一个指向 LFS 存储的文件的指针，而不是文件本身。

bash 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 及以上版本。

```
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 的内容。

- 禁用自动下载：

bash git lfs install \-\-skip\-smudge

\-\-skip\-smudge 选项会禁用在 git pull 或 git checkout 时自动下载 LFS 文件。

- 现在你可以正常拉取仓库内容，但 LFS 文件将不会被下载。仓库中的 LFS 文件会显示为指针文件。

- 当你需要下载特定的 LFS 文件时，可以使用：

bash git lfs pull

或者使用以下命令下载特定目录或文件的 LFS 文件：

bash 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 仓库过大的问题，而是区分文件的类型，在“同步”速度上下功夫。在“小容量设备部分同步仓库”的场景下，是一个很好的处理方案。

---

[前往标准阅读页](https://utgd.net/article/20870?audience=web)
