原来极客都是这样管理 dotfiles 的

大家好,我是极客老墨。

作为开发者,你肯定干过这种事:新买了台 MacBook,兴冲冲地打开,然后开始漫长的配置之旅——装 Neovim、调 VSCode、改 .zshrc、配 Git、搞主题、设快捷键……折腾了一整天,终于把环境调成自己熟悉的样子。

更惨的是,过了半年,你又换了台机器,或者不小心把配置改坏了,想恢复?抱歉,当时怎么配的已经忘得一干二净。

这种痛,我懂。所以今天咱们就来聊聊,怎么用 Git 管理这些配置文件(dotfiles),让你的开发环境可以"一键复制",随时回滚,多机器同步。

说实话,我折腾 dotfiles 管理已经好几年了。从最开始手动复制配置文件,到后来用 bare repository,再到现在的 symlink 方案,每种方法都试过,每种方法都有坑。今天就把这些年的经验全部掏出来,告诉你什么方法最靠谱。走起!

什么是 Dotfiles?

Dotfiles 就是那些以 . 开头的配置文件,比如:

  • .zshrc - Zsh 配置
  • .vimrc - Vim 配置
  • .gitconfig - Git 配置
  • .config/nvim/ - Neovim 配置
  • .config/wezterm/ - WezTerm 配置

这些文件决定了你的开发环境长什么样,用起来爽不爽。

为什么要管理 Dotfiles?

痛点 1:换机器就抓瞎

新买了台 MacBook,想把老机器的配置搬过来?

手动复制?太慢了,而且容易漏。

痛点 2:配置丢了找不回来

不小心改坏了配置,想恢复?

没有版本控制,只能重新配置。

痛点 3:团队协作困难

团队想统一开发环境?

每个人的配置都不一样,沟通成本巨大。

解决方案:用 Git 管理

把配置文件放到 Git 仓库:

  • 版本控制
  • 多机器同步
  • 团队共享
  • 随时回滚

方法一:Bare Repository(我用过,不推荐)

这是一种很"极客"的方法,不需要软链接,直接把 ~ 目录作为工作目录。

工作原理

 1# 初始化 bare repository
 2git init --bare $HOME/.cfg
 3
 4# 创建别名
 5alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
 6
 7# 隐藏未跟踪的文件
 8config config --local status.showUntrackedFiles no
 9
10# 添加配置文件
11config add ~/.zshrc
12config commit -m "Add zshrc"
13config push

在新机器上使用

 1# 克隆仓库
 2git clone --bare <repo-url> $HOME/.cfg
 3
 4# 创建别名
 5alias config='/usr/bin/git --git-dir=$HOME/.cfg/ --work-tree=$HOME'
 6
 7# 检出配置
 8config checkout
 9
10# 隐藏未跟踪的文件
11config config --local status.showUntrackedFiles no

优点

  • 配置文件在原位置,无需软链接
  • 简洁,不需要额外的目录
  • 原生 Git 操作

缺点(我踩过的坑)

1. 不直观

每次操作都要用 config 命令而不是 git,容易忘记。

1# 经常搞混
2git add ~/.zshrc     # 错误
3config add ~/.zshrc  # 正确

2. 容易误操作

因为工作目录是 ~,一不小心就会把不该跟踪的文件加进去。

1config add ~/Downloads/  # 完蛋,把下载目录加进去了

3. 新手不友好

别人克隆你的仓库后,需要理解 bare repository 的概念,学习成本高。

4. 难以组织

所有配置文件都在 ~ 目录下,无法按工具分类组织。

我的真实经历

用了半年 bare repository,最大的问题是:太容易出错了

有一次不小心 config add ~,把整个家目录都加进去了,花了半天时间清理。还有一次在公司电脑上忘记设置 showUntrackedFiles noconfig status 输出了几千行,直接卡死。

最后决定:放弃 bare repository,换回 symlink

如果你同样喜欢折腾,可以看看Atlassian 的 Dotfiles 教程

方法二:Symlink(我现在用的,推荐)

这是最常见、最稳妥的方法:把配置文件放到一个专门的目录,然后通过软链接指向实际位置。

老墨感悟:终于又从 base repository 换回来了,折腾得够呛!

工作原理

1~/dotfiles/nvim/init.lua  →  ~/.config/nvim/init.lua  (软链接)
2~/dotfiles/terminal/.zshrc  →  ~/.zshrc  (软链接)

配置文件实际存储在 你的存储路径/dotfiles/,但系统读取的是软链接指向的位置。

目录结构

dotfiles/
├── README.md
├── install.sh              # 安装脚本
├── uninstall.sh            # 卸载脚本
│
├── nvim/                   # Neovim 配置
│   └── init.lua
│
├── terminal/               # 终端配置
│   ├── .zshrc
│   └── .bashrc
│
├── git/                    # Git 配置
│   ├── .gitconfig
│   └── .gitignore
│
├── wezterm/                # WezTerm 配置
│   └── wezterm.lua
│
└── vscode/                 # VSCode 系列 IDE
    ├── keybindings.json
    └── settings.json

vscode 目录是我正在探索的一种管理 “类 VSCode IDE” 的通用方式,我想要实现一套配置适配所有的基于 VSCode 的 IDE,免得总是要导进来导出去,太麻烦了。

安装脚本

创建 install.sh

 1#!/bin/bash
 2
 3set -e
 4
 5DOTFILES_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 6
 7# 函数:创建软链接
 8create_symlink() {
 9  local source=$1
10  local target=$2
11  local name=$3
12  
13  echo "安装 $name"
14  
15  # 备份现有文件
16  if [ -e "$target" ] && [ ! -L "$target" ]; then
17    echo "  备份现有配置"
18    mv "$target" "${target}.backup.$(date +%Y%m%d_%H%M%S)"
19  fi
20  
21  # 删除现有软链接
22  [ -L "$target" ] && rm "$target"
23  
24  # 创建软链接
25  ln -sf "$source" "$target"
26  echo "  ✓ 创建软链接: $target -> $source"
27}
28
29# 安装 Neovim 配置
30[ -d "$DOTFILES_DIR/nvim" ] && \
31  create_symlink "$DOTFILES_DIR/nvim" "$HOME/.config/nvim" "Neovim"
32
33# 安装终端配置
34[ -f "$DOTFILES_DIR/terminal/.zshrc" ] && \
35  create_symlink "$DOTFILES_DIR/terminal/.zshrc" "$HOME/.zshrc" ".zshrc"
36
37# 安装 Git 配置
38[ -f "$DOTFILES_DIR/git/.gitconfig" ] && \
39  create_symlink "$DOTFILES_DIR/git/.gitconfig" "$HOME/.gitconfig" ".gitconfig"
40
41echo "✓ 所有配置安装完成!"

使用方法

首次安装

1# 克隆仓库
2git clone git@github.com:gkmz/dotfiles.git ~/dotfiles
3
4# 安装配置
5cd ~/dotfiles
6./install.sh

修改配置

1# 方式 A:直接修改 dotfiles(推荐)
2vim ~/dotfiles/nvim/init.lua
3
4# 方式 B:修改实际位置(效果相同)
5vim ~/.config/nvim/init.lua
6
7# 两种方式完全等价,因为是软链接

提交变更

1cd ~/dotfiles
2git add .
3git commit -m "配置: 更新 Neovim 配置"
4git push

同步到其他机器

1cd ~/dotfiles
2git pull
3# 配置自动生效

优点

1. 直观易懂

配置文件有清晰的组织结构,一目了然。

2. 安全

不会误操作,因为只跟踪 ~/dotfiles/ 目录。

3. 易于分享

别人克隆后直接运行 ./install.sh 就能用,不需要理解复杂的概念。

4. 灵活组织

可以按工具分类,添加 README,写详细的说明。

缺点

1. 需要软链接

多了一层间接关系,但这不是问题,因为软链接很稳定。

2. 需要安装脚本

但这也是优点,因为可以自动化安装过程。

我的最佳实践

1. 目录结构清晰

按工具分类,每个工具一个目录:

dotfiles/
├── nvim/           # Neovim
├── wezterm/        # WezTerm
├── lazygit/        # Lazygit
├── terminal/       # 终端配置
└── git/            # Git 配置

2. 敏感信息分离

不要把 API Keys、Tokens 提交到 Git。

使用 .local 文件

1# 在 .zshrc 末尾添加
2[ -f ~/.zshrc.local ] && source ~/.zshrc.local
3
4# 在 .zshrc.local 中存放敏感信息
5export OPENAI_API_KEY="your-key"
6export GITHUB_TOKEN="your-token"

.zshrc.local 加入 .gitignore,不提交到 Git。

3. 自动备份

安装脚本自动备份现有配置:

1mv "$target" "${target}.backup.$(date +%Y%m%d_%H%M%S)"

这样即使出错,也能从备份恢复。

4. 条件包含

对于 Git 配置,有时候我们需要为不同项目设置不同的用户信息,比如区分工作仓库和自己仓库的用户名、邮箱,可以通过条件包含来实现:

1# .gitconfig
2[includeIf "gitdir:~/workspace/work/"]
3    path = ~/.git_work
4
5[includeIf "gitdir:~/workspace/personal/"]
6    path = ~/.git_personal

5. 详细的 README

写清楚:

  • 包含哪些配置
  • 如何安装
  • 如何使用
  • 常见问题

实战:搭建你的 Dotfiles

第一步:创建仓库

1mkdir ~/dotfiles
2cd ~/dotfiles
3git init

第二步:复制配置文件

1# 创建目录结构
2mkdir -p nvim terminal git
3
4# 复制配置文件
5cp -r ~/.config/nvim/* nvim/
6cp ~/.zshrc terminal/.zshrc
7cp ~/.gitconfig git/.gitconfig

第三步:创建安装脚本

参考前面的 install.sh 示例。

第四步:创建 .gitignore

1# .gitignore
2*.local
3*.backup.*
4.DS_Store

第五步:提交到 Git

1git add .
2git commit -m "初始化 dotfiles"
3git remote add origin git@github.com:yourusername/dotfiles.git
4git push -u origin main

第六步:在新机器上使用

1git clone git@github.com:yourusername/dotfiles.git ~/dotfiles
2cd ~/dotfiles
3./install.sh

高级技巧

1. 多机器差异化配置

问题场景:你有多台机器(比如公司电脑和个人电脑),它们用同一套 dotfiles,但有些配置需要不一样。

比如:

  • 公司电脑需要配置代理,个人电脑不需要
  • 公司电脑用公司邮箱提交代码,个人电脑用个人邮箱
  • 不同机器的工作目录路径不同

如果每台机器都手动改配置,就失去了 dotfiles 统一管理的意义。

解决方案:在配置文件里根据主机名或其他条件判断,自动应用不同的配置。

 1# .zshrc
 2if [[ $(hostname) == "work-laptop" ]]; then
 3  # 工作电脑的配置
 4  export PROXY="http://proxy.company.com:8080"
 5  alias ws="cd ~/work/projects"
 6else
 7  # 个人电脑的配置
 8  export PROXY=""
 9  alias ws="cd ~/personal/projects"
10fi

这样一套配置文件,在不同机器上自动适配,不需要手动修改。

2. 模块化配置

将配置拆分成多个文件:

1# .zshrc
2source ~/.zsh/aliases.zsh
3source ~/.zsh/functions.zsh
4source ~/.zsh/exports.zsh

3. 自动化测试

创建测试脚本验证配置:

1#!/bin/bash
2# test.sh
3
4# 测试软链接是否正确
5[ -L ~/.zshrc ] && echo "✓ .zshrc 软链接正确" || echo "✗ .zshrc 软链接错误"
6[ -L ~/.config/nvim ] && echo "✓ nvim 软链接正确" || echo "✗ nvim 软链接错误"

常见问题

Q: 软链接会不会失效?

A: 不会。只要 dotfiles 目录不移动,软链接就一直有效。即使重启系统,软链接也不会失效。

Q: 如何处理二进制文件?

A: 不要把二进制文件放到 Git。如果必须,使用 Git LFS

Q: 如何同步插件?

A: 对于 Vim/Neovim,使用插件管理器(如 lazy.nvim),只提交配置文件,不提交插件本身。插件管理器会根据配置自动下载安装插件。

Q: 配置文件太大怎么办?

A: 拆分成多个文件,使用 sourceinclude 加载。比如把 .zshrc 拆分成 aliases.zshfunctions.zshexports.zsh 等。

我的 Dotfiles

我的完整 dotfiles 配置已经开源:

https://github.com/gkmz/dotfiles

包含:

  • Neovim 配置
  • WezTerm 终端配置
  • Zsh 配置
  • Git 配置(条件包含)
  • VSCode 系列 IDE 配置
  • Lazygit、Lazydocker 等工具配置

欢迎参考和 Star!

写在最后

从 bare repository 到 symlink,我终于找到了最适合自己的方式。

Bare repository 虽然极客,但不够实用。Symlink 虽然多了一层间接,但更稳定、更易用、更适合分享。

如果你还在手动管理配置文件,赶紧试试 dotfiles 管理吧。一次配置,终身受益。

平台说明

本文介绍的方法主要适用于 macOS 和 Linux。Windows 用户虽然也可以使用软链接(需要管理员权限),但由于 Windows 的配置文件管理方式不同(大多使用注册表或 AppData),dotfiles 的概念在 Windows 上并不常见。如果你是 Windows + WSL 用户,可以在 WSL 环境中使用本文的方法。

如果你也在用 dotfiles,欢迎在评论区分享你的方案。

极客老墨,继续折腾。

关注公众号:极客老墨

更多 AI 应用开发、工程实践和效率工具分享,欢迎扫码关注。

极客老墨微信公众号二维码

相关阅读