背景
很多开发者同时维护多个身份的项目,例如:
| 身份 | 邮箱 | GPG Key |
|---|---|---|
| 个人身份 | personal@example.com | Key A |
| 工作身份 | work@example.com | Key B |
希望达到以下效果:
~/code/personal/*
↓
personal@example.com
Key A
~/code/work/*
↓
work@example.com
Key B
即:
- 不同目录下的 Git 仓库自动使用不同邮箱
- 自动使用对应的 GPG Key 进行 Commit 签名
- 不需要每个仓库单独配置
Git 提供的 includeIf 功能可以很好地实现这一需求。
第一步:准备 GPG 密钥
查看本机所有 GPG 密钥:
gpg --list-secret-keys --keyid-format LONG
示例:
sec rsa4096/AAAAAAAAAAAAAAAA
uid Developer One <personal@example.com>
sec rsa4096/BBBBBBBBBBBBBBBB
uid Developer One <work@example.com>
记录需要使用的 Key ID:
个人身份:
AAAAAAAAAAAAAAAA
工作身份:
BBBBBBBBBBBBBBBB
第二步:配置默认身份
编辑全局配置文件:
vim ~/.gitconfig
内容如下:
[user]
name = Developer One
email = personal@example.com
signingkey = AAAAAAAAAAAAAAAA
[commit]
gpgsign = true
[gpg]
format = openpgp
[includeIf "gitdir:/Users/username/code/work/"]
path = ~/.gitconfig-work
说明:
- 默认情况下使用
personal@example.com - 默认使用
Key A - 当仓库位于
/Users/username/code/work/目录下时,额外加载~/.gitconfig-work
第三步:创建工作身份配置
创建配置文件:
touch ~/.gitconfig-work
编辑:
vim ~/.gitconfig-work
内容:
[user]
name = Developer One
email = work@example.com
signingkey = BBBBBBBBBBBBBBBB
[commit]
gpgsign = true
注意:
这里不需要再配置路径。
路径匹配规则已经写在:
~/.gitconfig
中的 includeIf 配置里。
第四步:理解 includeIf 工作原理
假设目录结构如下:
/Users/username/code/
├── personal
│ ├── blog
│ └── dotfiles
│
└── work
├── backend
├── frontend
└── service-a
配置:
[includeIf "gitdir:/Users/username/code/work/"]
path = ~/.gitconfig-work
表示:
只要 Git 仓库位于
/Users/username/code/work/
目录下
自动加载:
~/.gitconfig-work
因此:
/Users/username/code/work/backend
使用:
work@example.com
BBBBBBBBBBBBBBBB
而:
/Users/username/code/personal/blog
使用:
personal@example.com
AAAAAAAAAAAAAAAA
第五步:验证配置是否生效
进入工作项目:
cd ~/code/work/backend
查看邮箱:
git config user.email
输出:
work@example.com
查看签名 Key:
git config user.signingkey
输出:
BBBBBBBBBBBBBBBB
进入个人项目:
cd ~/code/personal/blog
查看邮箱:
git config user.email
输出:
personal@example.com
查看签名 Key:
git config user.signingkey
输出:
AAAAAAAAAAAAAAAA
第六步:查看 Git 实际加载的配置
排查问题时最有用的命令:
git config --list --show-origin
示例:
file:/Users/username/.gitconfig
user.email=personal@example.com
file:/Users/username/.gitconfig-work
user.email=work@example.com
说明:
Git 先加载 ~/.gitconfig
因为目录匹配
再加载 ~/.gitconfig-work
后加载的配置会覆盖前面的配置
第七步:测试 GPG 签名
创建测试提交:
git commit -S --allow-empty -m "test gpg"
查看签名:
git log --show-signature -1
示例:
gpg: Good signature from "Developer One <work@example.com>"
说明当前仓库已经使用对应身份完成签名。
常见问题
includeIf 不生效
检查路径是否完全一致:
[includeIf "gitdir:/Users/username/code/work/"]
建议:
- 使用绝对路径
- 保留末尾
/ - 路径大小写保持一致
查看当前仓库最终使用的邮箱
git config user.email
查看当前仓库最终使用的 GPG Key
git config user.signingkey
查看当前 Commit 使用的签名
git log --show-signature -1
扩展:配置多个身份
例如同时维护个人、工作、开源组织项目:
[includeIf "gitdir:/Users/username/code/work/"]
path = ~/.gitconfig-work
[includeIf "gitdir:/Users/username/code/opensource/"]
path = ~/.gitconfig-opensource
[includeIf "gitdir:/Users/username/code/client/"]
path = ~/.gitconfig-client
每个身份分别配置:
~/.gitconfig-work
~/.gitconfig-opensource
~/.gitconfig-client
即可实现根据项目目录自动切换 Git 邮箱和 GPG 签名密钥。
最终目录结构
~/.gitconfig
~/.gitconfig-work
~/.gitconfig-opensource
~/.gitconfig-client
~/code/personal/*
~/code/work/*
~/code/opensource/*
~/code/client/*
对应关系:
默认身份
↓
personal@example.com
Key A
work 目录
↓
work@example.com
Key B
opensource 目录
↓
opensource@example.com
Key C
client 目录
↓
client@example.com
Key D
这样即可实现根据仓库目录自动切换 Git 身份和 GPG 签名密钥。