我使用 obsidian-git 进行 0.0 Obsidian 介绍 笔记同步,随着 Vault 中大文件越来越多,我逐渐开始发愁:Git 并不适合处理大文件。直到我将一个 3.4GB 的视频加入 Vault Git 仓库,直接把 NAS 搞歇菜了……于是我想到了 Git LFS。
在本文中,我的目标是:Vault 仍然使用 Git 仓库,但开启 Git LFS,继续使用 obsidian-git 同步。同时,我对提交进行严格限制(通过 pre-commit
钩子),只有纯文本文件能进入 Git 仓库,其他所有二进制都走 LFS,都不会真正提交到 Git 仓库里。从而实现了既保持 Git 仓库的纯粹优雅,又能在 Vault 中存储大量二进制大文件。
我的 Git Server 基于 Gitea 运行在我的 NAS 上,因此容量不是问题。Vault 的大小只取决于我本地电脑硬盘的大小。这也不是问题,正是我所期望的,我希望的就是 0.0 Obsidian 介绍 “存一切”数据。这样,从一台电脑切换到另一台,或者买一台新电脑时,clone 一下 Vault,熟悉的味道,熟悉的感觉,一下子就回来了。
我在探索前,在 NAS 上备份了 Gitea 的 Docker 数据,在电脑上也复制了一份 Vault,并在 Gitea 上创建新 Repo 进行试验。这些操作保证新的尝试不会把已有数据搞损坏,一旦尝试失败,我立刻能回到现有状态,不会有任何损失。
事实证明,这是无比明智的。我在升级 Gitea 时,看容器不响应,手动停止了容器。可实际上 Gitea 正在数据库迁移,迁移一半终止,数据库直接损毁了,无法修复。好在我有备份,复制一份重新迁移,顺利完成。可见备份的重要性
在本地电脑上,将 Vault 目录复制一份,进入新仓库,删除已有的 .git
目录。在新仓库中重新创建 git 仓库,并开启 LFS 支持:
git init
git lfs install
# 关联远程仓库
git remote add origin ssh://git@仓库地址/maxiee/obsidian-notes-lfs.git
在 Linux 下,当路径中含有中文时,git 会以 "\nnn\nnn...
" 的格式展示,导致后续脚本运行失败。具体参见这篇网页。需要进行如下 git 设置:
git config core.quotepath off
这是我这次实践中非常有特色的部分。我只想让 git 管理纯文本文件,二进制都通过 lfs 托管。于是我通过一个 commit 钩子,实现自动拦截未经 LFS 跟踪的二进制文件,从而避免了二进制不小心被添加到 Git 库中,保证了 Git 库里只有纯文本。
在 Vault 的 .git/hooks
内创建如下 pre_commit
文件,它会首先根据一个文本文件的后缀白名单判断,在白名单内表示是纯文本,不拦截提交。如果是被 Git LFS 跟踪的二进制,而不拦截提交。如果都不是,则默认为二进制文件,阻塞提交。这样,开启 obsidian-git 的自动提交,遇到不支持的二进制,也会被拦下来。
#!/bin/sh
echo "正在检查提交的文件..."
# 保存原始的 IFS 值
OLD_IFS="$IFS"
# 只按照换行符分割
IFS=
显然,后缀白名单会导致误判。这没关系,只要手动维护这个白名单即可。
让钩子变为可执行权限:`chmod +x .git/hooks/pre_commit`。
---
## 提交所有 Markdown 文件
首先需要在新仓库中重新提交 Markdown。我有六千多篇 Markdown 笔记,于是我写了个脚本,一键 `git add` 仓库内所有 Markdown:
```sh
#!/bin/bash
# 设置您的 Obsidian Vault 目录的路径
VAULT_PATH="."
# 检查是否有文件扩展名作为参数传入
if [ $# -eq 0 ]; then
echo "请提供文件扩展名作为参数,例如:'.md'"
exit 1
fi
EXTENSION=$1
# 寻找所有指定扩展名的文件并添加到 Git 暂存区
find "$VAULT_PATH" -type f -name "*${EXTENSION}" -exec git add {} +
echo "所有 ${EXTENSION} 文件已添加到暂存区。"
这个脚本是通用的,支持任意后缀:./.obsidian/maeiee_scripts/commit_all_markdown.sh .md
。
git lfs track "*.epub"
之后,对 epub 文件正常 add、commit、push 即可,在命令行中能看到 LFS 上传提示。
注:如果不执行 git lfs track
,直接上传 Epub,会被 pre-commit 所拦截。
下图是开启 LFS 后的提交截图,性能和速度比起 Git 直接提交,要好上不少:
在 Gitea 项目设置的 LFS Tab 中,能够看到二进制文件:
下面尝试添加开头说的那个 3.4GB 的大视频。上传过程中速度非常快(这是我电脑 WIFI 的速度上限):
Uploading LFS objects: 50% (1/2), 3.2 GB | 41 MB/s
值得一提的是,这个过程电脑负载非常轻。Server 端压力也小得多。Git 直接处理二进制时,性能开销很大,同时在 Server 侧需要申请大量内存。而有了 Git LFS,实际上就是一个接口文件上传的事情。
这套系统配置好后,我准备手动同步一段时间。在这段时间里,细细查看过程中是否有什么问题。等到未来,打磨流畅、有了足够信心后,再将 obsidian-git 自动同步打开,这件事情便彻底完结了。
未来新电脑需要 clone repo 时,需要遵循以下步骤:
pre-commit
脚本,放入 .git/hooks
目录下\n'
for file in $(git diff --cached --name-only); do
lfs_attr=
if [[ $lfs_attr == "lfs" ]]; then
continue
fi
echo "错误: 文件 '$file' 不是文本文件,也未通过 Git LFS 跟踪。"
exit 1
done
IFS="$OLD_IFS"
exit 0
显然,后缀白名单会导致误判。这没关系,只要手动维护这个白名单即可。
让钩子变为可执行权限:`chmod +x .git/hooks/pre_commit`。
---
## 提交所有 Markdown 文件
首先需要在新仓库中重新提交 Markdown。我有六千多篇 Markdown 笔记,于是我写了个脚本,一键 `git add` 仓库内所有 Markdown:
{{CODE_BLOCK_3}}
这个脚本是通用的,支持任意后缀:`./.obsidian/maeiee_scripts/commit_all_markdown.sh .md`。
---
## 尝试 lfs track epub
{{CODE_BLOCK_4}}
之后,对 epub 文件正常 add、commit、push 即可,在命令行中能看到 LFS 上传提示。
注:如果不执行 `git lfs track`,直接上传 Epub,会被 pre-commit 所拦截。
下图是开启 LFS 后的提交截图,性能和速度比起 Git 直接提交,要好上不少:
![Pasted image 20240205021126.png](/img/user/998.%E9%99%84%E4%BB%B6%E4%BB%93%E5%BA%93/Pasted%20image%2020240205021126.png)
在 Gitea 项目设置的 LFS Tab 中,能够看到二进制文件:
![Pasted image 20240205021311.png](/img/user/998.%E9%99%84%E4%BB%B6%E4%BB%93%E5%BA%93/Pasted%20image%2020240205021311.png)
---
## 尝试 track 大视频
下面尝试添加开头说的那个 3.4GB 的大视频。上传过程中速度非常快(这是我电脑 WIFI 的速度上限):
{{CODE_BLOCK_5}}
值得一提的是,这个过程电脑负载非常轻。Server 端压力也小得多。Git 直接处理二进制时,性能开销很大,同时在 Server 侧需要申请大量内存。而有了 Git LFS,实际上就是一个接口文件上传的事情。
---
## 暂时关闭 [[obsidian-git]] 自动同步
这套系统配置好后,我准备手动同步一段时间。在这段时间里,细细查看过程中是否有什么问题。等到未来,打磨流畅、有了足够信心后,再将 [[obsidian-git]] 自动同步打开,这件事情便彻底完结了。
---
## 新电脑配置 Todo
未来新电脑需要 clone repo 时,需要遵循以下步骤:
1. 电脑安装 [[Git LFS]]
2. clone 仓库
3. 需要手动复制 `pre-commit` 脚本,放入 `.git/hooks` 目录下
本文作者:Maeiee
本文链接:Obsidian obsidian-git 使用 Git LFS 管理大文件
版权声明:如无特别声明,本文即为原创文章,版权归 Maeiee 所有,未经允许不得转载!
喜欢我文章的朋友请随缘打赏,鼓励我创作更多更好的作品!