GitHubのSSH接続で複数アカウントを使い分ける方法

プロジェクトによって使用する GitHub アカウントを切り替えたい！ということがあったので、個人的メモも兼ねて記事にしました。

# 環境
この記事は以下の環境で検証されています。
* Windows 11 Home ( 23H2 )
* git version 2.43.0.windows.1

# 事前準備

## Git for Windows のインストール
Terminal で以下のコマンドを実行するだけでインストールできます。
このコマンド実行時にエラーが出る場合は、別途 winget のインストールが必要です。
winget のインストール方法は [winget をインストールする](https://learn.microsoft.com/ja-jp/windows/package-manager/winget/#install-winget "winget をインストールする") を参照してください。
```shell:Terminal
winget install --id Git.Git -e --source winget
```
インストールされた Git のバージョンを確認しておきます。
```shell:Terminal
git -v
```
以下のように Git のバージョンが表示されれば正しくインストールされています。
```shell:Terminal
git version 2.43.0.windows.1
```

# 公開鍵と秘密鍵の作成
複数アカウントの切り替えが目的のため、公開鍵と秘密鍵を２ペア作成します。
GitHub のアカウント情報は以下の想定で説明します。
* プライベート用アカウント
  * ユーザー名：user_private
  * メールアドレス：user_private@example.com
* 仕事用アカウント
  * ユーザー名：user_work
  * メールアドレス：user_work@example.com

ホームディレクトリ配下に ```.ssh``` を作成。
既に ```.ssh``` が存在する場合は不要です。
```shell:Terminal
mkdir ~/.ssh
```
カレントディレクトリをホームディレクトリ配下の ```.ssh``` に変更。
```shell:Terminal
cd ~/.ssh
```

## プライベートアカウントの公開鍵と秘密鍵の作成
公開鍵と秘密鍵を作成するコマンドを実行します。
```shell:Terminal
ssh-keygen -t rsa -C user_private@example.com -f id_rsa_private
```
パスフレーズの入力を求められます。
入力したパスフレーズは画面には表示されません。入力できたら Enter で次へ進んでください。
このパスフレーズは自分で自由に設定できますが、Git を使用する中で度々入力を求められるものになりますので、忘れないように注意が必要です。
```shell:Terminal
Enter passphrase (empty for no passphrase):
```
パスフレーズ検証のために、もう一度入力を求められます。
先ほどと同じパスフレーズをタイプして Enter で次へ進みましょう。
```shell:Terminal
Enter same passphrase again:
```
以下のように表示されれば成功です。
```shell:Terminal
Your identification has been saved in c:/Users/[username]/.ssh/id_rsa_private
Your public key has been saved in c:/Users/[username]/.ssh/id_rsa_private.pub
The key fingerprint is:
     ~ 中略 ~
|            .    |
+----[SHA256]-----+
```

## 仕事用アカウントの公開鍵と秘密鍵の作成
手順は「プライベートアカウントの公開鍵と秘密鍵の作成」と同様です。キーを保存するファイル名を ```id_rsa_work``` に読み替えて、同じように公開鍵と秘密鍵を作成してください。
```shell:Terminal
ssh-keygen -t rsa -C user_work@example.com -f id_rsa_work
```

## 公開鍵と秘密鍵の確認
次のコマンドを実行することで、作成した公開鍵と秘密鍵のファイルを確認することができます。
```shell:Terminal
ls -l ~/.ssh
```
ここまで手順通りに進めてきた方は、以下のように４つのファイルが表示されると思います。
```shell:Terminal
C:\Users\[username]\.ssh

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2024/02/05     20:49           3414 id_rsa_private
-a----        2024/02/05     20:49            733 id_rsa_private.pub
-a----        2024/02/05     20:51           3414 id_rsa_work
-a----        2024/02/05     20:51            733 id_rsa_work.pub
```

# 公開鍵を GitHub へ登録
作成した公開鍵情報を GitHub へ登録します。

## プライベートアカウントの公開鍵情報を登録
以下のコマンドで ```id_rsa_private.pub``` の中身をクリップボードへコピーします。
```shell:Terminal
Get-Content ~/.ssh/id_rsa_private.pub | Set-Clipboard
```
次に [GitHub](https://github.com/settings/keys "SSH and GPG keys") をブラウザで開いて ```New SSH Key``` をクリックします。
この時、必ず **プライベート用アカウントで GitHub にログインしていること** を確認してください。
![2024-02-06_00h57_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702870/fa378d68-f8c9-03c0-3ede-dc4bd8963bbc.png)

```Title``` を入力して、クリップボードにコピーしておいた公開鍵情報を ```Key``` フォームに貼り付けます。
```Key type``` は ```Authentication Key``` のまま変更の必要はありません。
最後に ```Add SSH key``` ボタンをクリックして完了です。
![2024-02-06_01h01_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702870/608373ff-3dfa-0084-83e1-5542e11282d7.png)

## 仕事用アカウントの公開鍵情報を登録
手順は「プライベートアカウントの公開鍵情報を登録」と同様です。

以下のコマンドで ```id_rsa_work.pub``` の中身をクリップボードへコピーします。
```shell:Terminal
Get-Content ~/.ssh/id_rsa_work.pub | Set-Clipboard
```
次に [GitHub](https://github.com/settings/keys "SSH and GPG keys") をブラウザで開いて ```New SSH Key``` をクリックします。
この時、必ず **仕事用アカウントで GitHub にログインしていること** を確認してください。
![2024-02-06_00h57_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702870/fa378d68-f8c9-03c0-3ede-dc4bd8963bbc.png)

```Title``` を入力して、クリップボードにコピーしておいた公開鍵情報を ```Key``` フォームに貼り付けます。
```Key type``` は ```Authentication Key``` のまま変更の必要はありません。
最後に ```Add SSH key``` ボタンをクリックして完了です。
![2024-02-06_01h24_58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2702870/e5727145-850e-ea7a-e505-1870733d7efa.png)

# GitHub アカウントを簡単に切り替える仕組みづくり

## SSH コンフィグファイルの作成
```~/.ssh``` フォルダの中に ```config``` というファイルを作成し、ファイルの中身は以下のように記述します。
```config:config
#プライベート用アカウント
Host github-private
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_private
  User git
  TCPKeepAlive yes
  IdentitiesOnly yes

#仕事用アカウント
Host github-work
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_work
  User git
  TCPKeepAlive yes
  IdentitiesOnly yes
```

## 作成したファイルの確認
ここまでの手順を実施した結果、```~/.ssh``` フォルダに５つのファイルが作成できていることを確認しておきましょう。

```shell:Terminal
ls -l ~/.ssh
```
```shell:Terminal
C:\Users\[username]\.ssh

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2024/02/05     20:56            250 config
-a----        2024/02/05     20:49           3414 id_rsa_private
-a----        2024/02/05     20:49            733 id_rsa_private.pub
-a----        2024/02/05     20:51           3414 id_rsa_work
-a----        2024/02/05     20:51            733 id_rsa_work.pub
```

# GitHub への SSH 接続テスト
以下のコマンドで確認します。
```{Host}``` 部分は ```~/.ssh/config``` ファイルで設定した ```Host``` を設定します。
```shell:Terminal
ssh -T {Host}
```
プライベート用アカウントで接続確認
```shell:Terminal
ssh -T github-private
```
パスフレーズの入力を求められるので、公開鍵作成時に入力したパスフレーズをタイプします。
```shell:Terminal
Enter passphrase for key 'C:\Users\[username]/.ssh/id_rsa_private':
```
接続に成功すると以下の様なメッセージが表示されます。
```shell:Terminal
Hi user_private! You've successfully authenticated, but GitHub does not provide shell access.
```
仕事用アカウントで接続確認
```shell:Terminal
ssh -T github-work
```
パスフレーズの入力を求められるので、公開鍵作成時に入力したパスフレーズをタイプします。
```shell:Terminal
Enter passphrase for key 'C:\Users\[username]/.ssh/id_rsa_work':
```
接続に成功すると以下の様なメッセージが表示されます。
```shell:Terminal
Hi user_work! You've successfully authenticated, but GitHub does not provide shell access.
```

# git clone / git add する方法
```{Host}``` 部分は ```~/.ssh/config``` ファイルで設定した ```Host``` を設定します。
```shell:Terminal
git clone git@{Host}:username/repository.git
git remote add origin git@{Host}:username/repository.git
```
```shell:Terminal
# プライベート用
git clone git@github-private:username/repository.git
git remote add origin git@github-private:username/repository.git
# 仕事用
git clone git@github-work:username/repository.git
git remote add origin git@github-work:username/repository.git
```

# 最後に
今回は SSH 接続で切り替える方法を整理しました。
https 接続でも切り替える方法はあるみたいですが、それはまたの機会に。
```direnv``` を使って自動で切り替える方法もある様なので、気になる方は調べてみると良いかもしれません。