macOS 外接硬盘开发总出现 ._ 文件,如何用 APFS 镜像彻底解决
在 macOS 上把代码仓库直接放在外接硬盘里开发,很多人都会遇到一个很烦的问题:只要修改文件,目录里就会冒出 ._package.json、._README.md 这类 ._ 开头的同名文件。它们不仅影响 Git 状态,还会干扰编辑器和搜索结果。
如果你的外接硬盘文件系统是 exFAT,那么这个问题通常不是项目本身造成的,而是 macOS 在兼容 exFAT 时生成的 sidecar 文件。项目里把它们忽略掉只能减少干扰,不能真正阻止它们再次出现。
需求
我的诉求其实很明确:
- 项目仍然放在外接硬盘里,方便容量扩展和多机器管理。
- 开发时不要再不断生成
._*这类垃圾文件。 - 新项目可以统一放在一个固定路径下,后续
git clone更顺手。 - 尽量不要改动现有仓库内容,旧项目我可以自己重新 clone。
如果只是想临时缓解,可以在项目里加上 .gitignore:
._*
同时也可以在编辑器里把 ._* 隐藏掉。但这类做法只是“看不见”,不是“不会再生成”。
方案
更稳妥的做法,是不要继续直接在 exFAT 目录里开发,而是在这块外接硬盘上创建一个 APFS sparse image,把它当作真正的开发工作盘使用。
这样做的核心原因是:
exFAT不原生支持 macOS 的部分扩展属性。- macOS 为了保存这些元数据,会在旁边生成
._文件名。 APFS原生支持这些元数据,所以在 APFS 卷里开发,通常不会再反复产生._*。
我这里把卷名直接定成 github,这样以后所有新项目都统一放到:
/Volumes/github
1. 创建 APFS sparse image
下面这套命令会在外接硬盘里创建一个名为 github-workspace.sparseimage 的 APFS 镜像文件,并把挂载卷名设为 github:
cd /Volumes/Elements/code
hdiutil create -size 200g -type SPARSE -fs APFS -volname github "/Volumes/Elements/code/github-workspace.sparseimage"
参数说明:
-size 200g表示镜像的最大容量上限是 200GB。-type SPARSE表示稀疏镜像,实际只会按已使用空间增长。-fs APFS表示镜像内部文件系统使用 APFS。-volname github表示挂载后会出现在/Volumes/github。
2. 挂载开发盘
创建完成后,执行:
hdiutil attach "/Volumes/Elements/code/github-workspace.sparseimage"
挂载成功后,你会看到一个新目录:
/Volumes/github
之后新的项目都直接放这里,不再放回原来的 exFAT 目录。
3. 新项目直接 clone 到 /Volumes/github
例如:
cd /Volumes/github
git clone https://github.com/openHacking/PyDeskUI.git
以后你也可以继续这样创建新的工作目录:
cd /Volumes/github
mkdir my-next-project
4. 日常什么时候挂载和卸载
这个镜像可以理解成一个“逻辑开发盘”。
开始开发前,先挂载:
hdiutil attach "/Volumes/Elements/code/github-workspace.sparseimage"
当天不再需要访问 /Volumes/github 时,再卸载:
hdiutil detach "/Volumes/github"
通常可以这样理解:
attach:开始工作,把开发盘接上。detach:收工后安全移除开发盘。
如果卸载失败,一般是因为 VS Code、Finder 或终端还在占用 /Volumes/github 下的文件。先关闭相关窗口,再执行一次 detach 即可。
5. 这样做之后还有没有 ._*
如果你继续直接在 exFAT 路径里工作,比如:
/Volumes/Elements/code/github/some-project
那么 ._* 仍然可能再次出现。
如果你改为在 APFS 镜像挂载出来的目录里工作,比如:
/Volumes/github/some-project
那么这类文件通常就不会再反复出现了。
总结
._* 文件的根因,通常不是项目代码有问题,而是 macOS 在 exFAT 外接硬盘上保存扩展属性时产生的 sidecar 文件。
真正有效的思路不是继续和 ._* 对抗,而是把开发目录迁移到一个 APFS 环境中。对外接硬盘用户来说,APFS sparse image 是一个很实用的折中方案:
- 不需要重格式化整块硬盘。
- 仍然可以继续把数据放在外接盘里。
- 新项目路径统一,管理起来更清晰。
- 可以从根源上减少甚至避免
._*文件反复出现。
如果你只是想继续开发新项目,一个最省事的习惯就是:把旧的 exFAT 目录当作存档区,新的仓库统一 clone 到 /Volumes/github。

评论