SMB 网络盘上的 Git 锁文件:一个网络文件系统引发的坑

712 字
4 分钟
SMB 网络盘上的 Git 锁文件:一个网络文件系统引发的坑

把 Git 仓库放在网络盘上(比如用 Obsidian 管理一个远程服务器上的笔记库,本地通过 SMB 挂载),平时没事,某次网络抖动之后,Git 突然全部操作报错

fatal: Unable to create '.git/index.lock': File exists.
fatal: cannot lock ref 'HEAD': Unable to create '.git/refs/heads/main.lock': File exists.

添加、提交、推送全挂了。这是 Git 的锁文件机制在网络文件系统上被”坑”了。

根因:网络文件系统不保证原子删除#

Git 的锁机制依赖文件系统的一个原子操作:创建锁文件用 O_CREAT | O_EXCL——“如果文件不存在就创建,存在就报错”,这个操作是原子的,用来防止两个进程同时写。

但在 SMB 网络文件系统上,这个保证不牢靠。网络抖动时:

  1. Git 进程创建了锁文件(index.lock
  2. 删除锁文件的操作因为 SMB 网络延迟 / 抖动失败
  3. 锁文件残留在 .git 目录里
  4. 下次任何 Git 操作看到锁文件存在 → 认为”有进程正在写” → 拒绝执行

网络断一下,锁就永远留下来了。

哪些锁文件会阻塞什么#

锁文件阻塞的操作
.git/index.lock任何改暂存区的操作(addcommit
.git/HEAD.lock改 HEAD(commitmergerebase
.git/refs/heads/*.lock更新分支引用(commitpushpull

立即修复:删掉残留锁文件#

在仓库根目录执行:

Terminal window
find .git -name "*.lock" -delete

Windows 命令提示符:

del /q .git\index.lock .git\HEAD.lock 2>nul
del /q .git\refs\heads\*.lock 2>nul

注意:删锁文件前确认没有 Git 进程在真正运行——如果有个卡死的 Git 进程握着锁,删了也会被重新创建。

预防:降低碰撞概率#

1. 降低自动提交频率。 如果用了”自动备份”类插件(定时自动 commit),把间隔调大到 10-30 分钟。自动提交越频繁,并发碰撞的概率越高。

2. 避免设置包装脚本。 某些工具支持配置自定义 Git 路径 / 包装脚本,但配置可能被迁移到工具内部存储里,之后即使从配置文件删掉也不生效——必须在工具设置界面里手动清空。

3. 考虑本地 + 远程双副本。 如果对可靠性要求高,把仓库放本地,通过同步工具推送到远程,而不是直接在网络盘上跑 Git。

一句话经验#

网络文件系统(SMB / NFS / 网盘)对 Git 的原子锁操作支持不稳定。仓库尽量放本地盘,放网络盘就要接受”网络抖动 = 锁残留”的风险,并准备好清理手段。

这不是 Git 的 bug,是”网络文件系统不保证本地盘语义”这个通用事实。凡是依赖原子操作的工具(数据库、Git、构建缓存),放在网络盘上都要多一份警惕。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或打赏支持!

打赏
SMB 网络盘上的 Git 锁文件:一个网络文件系统引发的坑
https://heaven-1314.github.io/posts/smb-git-lock-files/
作者
赵培州
发布于
2026-08-05
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
赵培州
AI 应用研发工程师 · 用 Agent 做默认交付
公告
记录 AI 应用落地实践与踩坑经验,欢迎交流。
分类
标签
最新动态
站点统计
文章
32
分类
9
标签
81
总字数
41,808
运行时长
0
最后活动
0 天前
站点信息
构建平台
GitHub Actions
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0