複数のGitHubアカウントをWSL経由のDevcontainerで使う
Webエンジニアの4096mgです。
複数のGitHubアカウントをWSL経由のDevcontainerで使うときに設定していることを備忘録として残しておきます。
仕事用と個人用で複数のGitHubアカウントを使い分けたいという需要は大きいと思いますが、Windowsに対応した情報はあまり見つからず、Devcontainerがどの認証情報を参照するかもわかりにくく、ハマりやすいポイントだと思います。
Windowsでは
- WindowsからそのままGitHubに接続したいとき
- WSLからGitHubに接続したいとき
- WSL経由のDevcontainerからGitHubに接続したいとき
の3つの接続パターンがあると思いますが、「Windowsから接続したいとき」「Devcontainerから接続したいとき」に問題なく動作するようにするのが目標です。
ここでは name1
と name2
の2つのアカウントを運用する想定でメモを残していきますが、3つ以上に増えても対応できると思います。
とりあえず説明を省いて作業手順を書き残しています。具体的に何故、何を設定しているのかといったことは記事の終わりに載せておきますので、知りたい方をそちらをご確認ください。
前提
- WindowsにGitがインストールされている
- WindowsでOpenSSHが有効化されている (最近ではデフォルトで有効)
- WindowsにWSL2とそのディストリビューションがインストールされている
- WindowsにVS Codeがインストールされている
- WSL経由でDevcontainerを立ち上げる用意が整っている (Dockerの導入など)
GitHubとSSHの設定
SSH Keyの作成と登録
まずは一般的なベストプラクティス通りに、GitHub登録用の鍵を2つ作成し、GitHubに登録します。
操作は Windows のターミナルアプリから行っています。
もし、 Windows Powershell がデフォルトになっている場合は、 Microsoft の推奨に従ってPowershell7をインストールし、デフォルト設定を切り替えることをおすすめします。(必須ではありません)
$ ssh-keygen -t ed25519 -f [name1]-github -C "[name1-gitHub-public-email]@users.noreply.github.com"
$ ssh-keygen -t ed25519 -f [name2]-github -C "[name2-gitHub-public-email]@users.noreply.github.com"
パスフレーズは設定してもしなくてもどちらでも問題ありません。お好みや社内規定に従ってください。
区別しやすいようにコメントには GitHub Public Email を書いています。
GitHub Public Email とは?
Git で使用する Email は一般に公開されます。スパム対策などのために GitHub では公開用のエイリアスが使えます。
メールアドレスは数字+ユーザー名@users.noreply.github.com
のようなフォーマットになっています。
GitHub の Settings の Email Settings の Primary email address のセクションで確認できます。
作成後、 GitHub の Settings の SSH and GPG keys セクションから各アカウントに SSH Key を登録します。
SSH Configの設定
次に、各アカウントの SSH Config を設定します。 C:\Users\[Windows Username]\.ssh\config
を編集します。
Host [name1]-github
HostName github.com
User git
Port 22
IdentityFile "~/.ssh/[name1]-github"
ForwardAgent yes
TCPKeepAlive yes
IdentitiesOnly yes
AddKeysToAgent yes
Host [name2]-github
HostName github.com
User git
Port 22
IdentityFile "~/.ssh/[name2]-github"
ForwardAgent yes
TCPKeepAlive yes
IdentitiesOnly yes
AddKeysToAgent yes
設定更新後、 ssh
コマンドを使って各アカウントの疎通確認を行います。近年の Windows では OpenSSH が自動で有効化されているはずですが、もしインストールや有効化が必要な場合はあわせて行います。
$ ssh -T [name1]-github
Hi name1! You've successfully authenticated, but GitHub does not provide shell access.
$ ssh -T [name2]-github
Hi name2! You've successfully authenticated, but GitHub does not provide shell access.
GitHub はシェル操作を許可していないため、挨拶メッセージが1行表示されるだけですが、きちんと表示されれば問題ないはずです。
各GitHubアカウント用のディレクトリを設定する
次に、WSL内部に各GitHubアカウント用のディレクトリを作成します。
Windowsのストレージに作成するのではなく、必ずWSL内部に作成するようにします。これによってパフォーマンスの問題が大幅に改善されます。
ディストリビューションなど、各自違うと思いますので、作成コマンドなどは乗せません。
自分はエクスプローラーのアドレスバーに \\wsl$
と入力してWSLの内部にアクセスし、ユーザーの home
ディレクトリの中に作成しています。
ここでは \\wsl.localhost\Ubuntu\home\[WSL Username]\github-storage
内に name1
と name2
のディレクトリ作成したという前提で進めていきますが、ディストリビューションやユーザー名によってパスは異なりますので、適宜書き換えてください。
Gitconfig を設定する
グローバルのGitconfigを設定
次に、WindowsのグローバルのGitconfig ( C:\Users\[Windows Username]\.gitconfig
) を以下のように設定します。
もし、グローバルでコミット時の名前やメールアドレスが設定されていればそれも消去します。
[user]
useconfigonly = true
[includeif "gitdir://wsl.localhost/Ubuntu/home/[WSL Username]/github-storage/name1/"]
path = //wsl.localhost/Ubuntu/home/[WSL Username]/github-storage/name1/.gitconfig
[includeif "gitdir://wsl.localhost/Ubuntu/home/[WSL Username]/github-storage/name2/"]
path = //wsl.localhost/Ubuntu/home/[WSL Username]/github-storage/name2/.gitconfig
[safe]
directory = %(prefix)///wsl.localhost/Ubuntu/home/[WSL Username]/github-storage/*
各アカウント用のディレクトリを設定
そして、各GitHubアカウント用のディレクトリにも個別のGitconfigを設定し、Git Hooksファイルも作成します。
ここでは [name1]
アカウントのものを記載しますが、 name2
にも同様の設定をします。
まずは、 .gitconfig
を作成します。 パスは //wsl.localhost/Ubuntu/home/[WSL Username]/github-storage/[name1]/.gitconfig
です。
[core]
hooksPath = //wsl.localhost/Ubuntu/home/[WSL Username]/github-storage/[name1]/.git-hooks
[url "git@[name1]-github:"]
insteadof = git@github.com:
次に、Git Hooksファイル github-storage/[name1]/.git-hooks/post-checkout
を作成します。
#!/bin/sh
GIT_USER_NAME="name1"
GIT_USER_EMAIL="[name1-gitHub-public-email]@users.noreply.github.com"
MARKER_FILE=$(git rev-parse --git-dir)/.initialized
if [ ! -f "$MARKER_FILE" ]; then
echo "Running setup for the first clone..."
git config user.name "$GIT_USER_NAME"
git config user.email "$GIT_USER_EMAIL"
echo "Git user.name and user.email have been set for this repository:"
git config user.name
git config user.email
touch "$MARKER_FILE"
fi
設定をすると、
- 名前とメールアドレスをリポジトリごとに設定する
- 指定したディレクトリ内にリポジトリを設置する
このどちらかを行わない限り、コミットできないようになります。
コミット時に名前やメールアドレスが別のアカウントのものになってしまうといった事故は複数のGitアカウントを運用するうえでとても恐ろしいです。
SSH Agent を自動永続起動にする
次に、Windowsで管理者権限のPowershellを起動し、SSH Agent の自動永続起動の設定をします。
$ Get-Service ssh-agent
// stoppedになっていることを確認
$ Set-Service -Name ssh-agent -StartupType 'Automatic'
$ Start-Service ssh-agent
これで、すべての設定は完了です。
作業手順の解説
なぜ、こんな回りくどい設定をしなければいけないのかなど、理由を書いておきますので、興味があればご確認ください。
SSH Agent と Git Hooks を利用している理由
複数のGitHubアカウントを運用するうえで、事故を防ぐため、グローバルのユーザー設定を使わないということはマストだと考えています。
そのために グローバルの .gitconfig
で useconfigonly = true
を設定し、 [includeif]
で指定したディレクトリの内部だけに設定を適用させるという手法はよく見られます。
しかし、これはDevcontainer内部では機能しません。
VS Code の Devcontainer は、立ち上げ時にユーザーホームにある .gitconfig
を自動でマウントしてくれます。
ですが、 .gitconfig
内の [includeif]
で指定したディレクトリのコンフィグまでは読み取ってくれません。
ディレクトリごとの名前とメールアドレスの設定というものは、 Devcontainer の内部では利用できません。
結局、Devcontainer 内用に、リポジトリごとの個別設定は必須になってしまいます。
ですので、最初に Windowsで git clone
を実行したときに、自動でユーザー設定を行うようにしてあります。
また、 Devcontainer では SSH Agent の鍵情報は参照してくれますが、SSH Configは参照してくれません。
そのため、git clone git@[name1]-github:[name1]/hello-world.git
のように、ベストプラクティスとしてあげられているような、 Gitのパスにある github.com をSSH Configのものに書き換える手法は機能しません。
そこで、パスの設定は通常通り github.com
にして、 Windows側 から接続するときだけ、 Gitconfigを使ってパスを書き換えています。
SSH鍵のパスフレーズへの対応ですが、こちらはSSH Agentを使って対応しています。一度Windowsでパスフレーズを入力すれば、SSH Agentを参照している Devcontainer 内でも利用が可能になります。別のアカウントの Devcontainer に接続するときだけ、鍵情報を消去する必要がありますが、手間としては許容範囲内だと考えています。
WindowsはWSL周りで無駄に複雑、GitHubはマルチアカウントまわりの規約が厳しいという経緯もあってマルチアカウント運用に弱い、Devcontainerは何がマウントされているのかわかりにくい、ということで最初は大変かと思いますが、一度設定してしまえば快適です。
まとめ
設定がすべて完了したら、あとは、
- リポジトリをWindows側で初回だけ
git checkout
しておく(git clone
コマンドを実行すれば自動でcheckoutも実行されます) - Windowsを起動後、Devcontainerを立ち上げる前に
ssh -T [name1]-github
して SSH Agent に鍵を登録する - 鍵を登録後、別アカウントのDevcontainerに切り替えるときは、
ssh-add -D
で鍵を消去してから 2 を再度実行する
この3つを守るだけで事故なくエラーなく開発できるようになるので、すごく快適です。
Windows側からGit Cloneなどの操作を行うときは、
PS > cd "\\wsl.localhost\Ubuntu\[WSL Username]\github-storage\[name1]"
PS > git clone git@github.com:[name1]/hello-world.git
のように、各アカウント用のディレクトリに移動してからgitコマンドを使用すれば、gitのパスをssh設定に合わせて書き換えることなく、リポジトリへの接続ができます。
また、VS Code上でも、最近 GitHub の複数アカウントのログイン に対応したため、こちらを活用していけば拡張機能なども不自由なく使えると思います。
最小限の労力で事故のない開発を目指して、設定を工夫していければ幸せですね。
最後に、この記事の執筆にあたって、 こちらのGist を参考にさせていただきました。感謝申し上げます。

ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion