日常在公司仓库(Macquarie SSO)和个人仓库之间切换时,最怕的就是”用错身份 push”或者”AWS 权限对不上”。这篇记录一次真实的排查过程:从一行诊断命令拆解开始,最后理清 includeifdirenv 这两个经常被搞混的机制到底谁管什么。

Part 1:拆解一段诊断命令

排查的起点是这样一段命令(只分析,不执行):

echo "--- local ---"; git -C ~/ws/qa/edr-nonstandard-etl config --local --get-regexp 'ssh|url|core\.' 2>/dev/null
echo "--- global ---"; git config --global --get-regexp 'ssh|url|includeif|core\.ssh' 2>/dev/null
echo "--- direnv allow list ---"; ls ~/.local/share/direnv/allow 2>/dev/null | head; direnv status 2>&1 | head -8

第一段 — 查看 local repo 的 git 配置

git -C ~/ws/qa/edr-nonstandard-etl config --local --get-regexp 'ssh|url|core\.'

第二段 — 查看 global git 配置

git config --global --get-regexp 'ssh|url|includeif|core\.ssh'

同理,但看的是 ~/.gitconfig,多加了 includeif(条件性引入其他配置文件,常用于”公司目录用这套 SSH key,个人目录用另一套”)。

第三段 — 查看 direnv 授权列表

ls ~/.local/share/direnv/allow 2>/dev/null | head
direnv status 2>&1 | head -8

整体来看,这套命令是在验证:”这个仓库到底用的是哪个 SSH 身份 / URL 重写规则,direnv 有没有 allow 这个目录” —— 典型的多身份环境排查思路。

Part 2:includeif vs direnv,一句话区分

includeif 管的是”我是谁”(git identity),direnv 管的是”我在哪个环境里”(env vars / PATH / secrets)。一个改身份证,一个换钱包。

includeif:按目录自动切换 git 身份

写在 ~/.gitconfig 里:

[includeif "gitdir:~/ws/mq/"]
    path = ~/.gitconfig-macquarie

[includeif "gitdir:~/ws/personal/"]
    path = ~/.gitconfig-personal

🩸 血泪提醒gitdir: 匹配的是仓库目录本身.git 所在位置),如果你是通过 symlink 或者 worktree 进去的,路径匹配可能对不上——这时候要用 gitdir/i:(大小写不敏感)或者干脆写绝对路径 debug。

direnv:按目录自动加载 shell 环境

.envrc 文件 + direnv allow

# ~/ws/mq/edr-nonstandard-etl/.envrc
export AWS_PROFILE=mqu-dev
export GIT_SSH_COMMAND="ssh -i ~/.ssh/mq_id_ed25519"

🩸 血泪提醒.envrc 里的代码是真实执行的 shell 脚本,不是声明式配置。如果 git pull 下来一个陌生仓库自带 .envrc,千万别无脑 direnv allow——这等于允许别人的脚本在你机器上跑任意命令。

组合拳怎么打

includeif 只改 git 层面的身份,不会自动把对应的 SSH key 加到 agent 里,也不会切 AWS profile。所以完整链条是:

进入 ~/ws/mq/edr-nonstandard-etl/
   ↓ direnv 自动加载
GIT_SSH_COMMAND 指向 mq 的 key + AWS_PROFILE=mqu-dev
   ↓ includeif 匹配 gitdir
git identity 切换成 macquarie 邮箱

两个系统各管一段,任何一段没配对,就会出现”用错身份 push”或者”AWS 权限对不上”这种坑

小结