複数のGitHubアカウントを使用する

普段用と仕事用などで複数のgithubアカウントを使い分ける必要があったので、その方法をメモする。

まず、前提として複数のgithubアカウントで同一のSSH keyを登録することはできないことに注意する。 アカウントごとに別のSSH鍵を作る必要がある。

鍵を作って登録したら、次のように${HOME}/.ssh/configを設定する。

# プライベート用の GitHub アカウントで利用する接続設定
Host github.com
    HostName github.com
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    User git

# 仕事用の GitHub アカウントで利用する接続設定
Host github.com.organizationA
    HostName github.com
    IdentityFile ~/.ssh/id_rsa
    IdentitiesOnly yes
    User git

IdentitiesOnly yesは入れておくべき設定である。 そうしないと、IdentityFileに書かれたのと異なる鍵が使われることを許すことになる。

次に、${HOME}/.gitconfigを次のように設定する。

[user]
        name = [[main account name]]
        email = [[main account email]]

[includeIf "gitdir:~/repos/organizationA/"]
        path = ~/.gitconfig.organizationA

また、${HOME}/.gitconfig.organizationAは次のように設定する。

[user]
        name = [[account name for organizaion A]]
        email = [[account email for organization A]]

[url "git@github.com.organizationA:"]
        insteadOf = git@github.com:

[url "ssh://git@github.com.organizationA/"]
        insteadOf = ssh://git@github.com/

[url "git@github.com.organizationA:"]
        insteadOf = https://github.com/

この2つの設定で、${HOME}/repos/organizaionA以下に配置するリポジトリについては、organizationA向けの設定がロードされて、 ユーザー名・Emailアドレスが自動的に設定される。 また、URLの書き換えも行っているので、単純にgithub.comのままクローンしたりしても大丈夫である。 仮に、クローンした組織のリポジトリがプライベートなサブモジュールを持っていて、相対パスで指定されていないような場合でも、この書き換え機能によって プロトコルはSSHに統一されるし、鍵も自動で選択されるようになる。

これで、基本的に大丈夫なようになったが、devcontainerを使用するプロジェクトの場合これでは上手く行かない。 私は、devcontainer.jsonに直接、2つのファイルをマウントする設定を書くことにした。

{
  "mounts": [
    "source=${localEnv:HOME}/.ssh,target=/home/dev/.ssh,type=bind,readonly",
    "source=${localEnv:HOME}/.gitconfig.organizationA,target=/home/dev/.gitconfig,type=bind,readonly"
  ]
}

幸い、私のプロジェクトではdevcontainer.jsonはリポジトリで直接は管理されず、 devcontainer.example.jsonを各自コピーして適当に書き換えて使用するという方針だったので、これで上手く行った。

devcontainer.jsonを直接リポジトリ内で管理しているプロジェクトの場合は、少し考えなければならないが、 それほど変更がないものなら、ローカルで上のようにマウント設定を書いておいて、 次のコマンドでワークツリー内のdevcontainer.jsonを無視してしまえばよいだろうと思っている。

git update-index --skip-worktree .devcontainer/devcontainer.json

これ以上複雑化する場合は、そもそもOSのユーザーを分けてしまうのが良いと思われる。