gitで複数のアカウントを切り替える方法

# 初めに
本記事はgithub等をSSH接続で利用する場合を考えて話を進めます。

多くのサーバークライアントプログラムではユーザー名とパスワードをサーバーに送信して認証を行い、セッションを確立します。セッション確立の際にセッションIDが発行され、それを保存することでログイン状態を保持します。
しかし、gitのSSHを用いた接続ではそれらの代わりに**秘密鍵**と**公開鍵**を使用します。公開鍵認証では、ユーザーは事前に生成した公開鍵をリモートリポジトリのアカウントに登録します。

つまり、Gitで複数アカウントを切り替えるには、いかにSSH鍵を切り替えるかが問題となるわけです。



# 環境
Windows11
git version 2.42.0.windows.2

# 手順
順に説明する。
## 1 公開鍵、秘密鍵の生成
```
$ cd ~/.ssh
```
まずhomeディレクトリ内の.sshに移動する。
```
$ ssh-keygen -f id_rsa_(任意の名前)
```
次に`ssh-keygen`コマンドで鍵を生成。
-f オプションは生成するファイル名を指定する。
利用するアカウントの数だけここで鍵を生成しておく。

:::note info
ssh-keygenを実行すると入力を求められますがEnter連打でも大丈夫です。
:::

## 2 公開鍵の登録
`ssh-keygen`コマンドの実行によって`~/.ssh`内に`id_rsa_(任意の名前)`と`id_rsa_(任意の名前).pub`の二つのファイルが生成される。前者が秘密鍵で、後者が公開鍵である。`id_rsa_(任意の名前).pub`の方をメモ帳などで開くと中身が
```
ssh-rsa (英数字の羅列) (端末名など)
```
になっている。`ssh-rsa (英数字の羅列)`の部分をコピー。
github等にアクセスし、公開鍵としてコピーした文字列を登録する。

全てのアカウントについてこの作業を行う。
## 3 Configの設定
```
$ cd ~/.ssh
$ type nul > config
```
`~/.ssh`内にssh用の`config`ファイルを作成する。
ファイルには次のように記述する。
```:config
Host github-(任意の名前1)
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_(任意の名前1)
  User git
  IdentitiesOnly yes

Host github-(任意の名前2)
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_(任意の名前2)
  User git
  IdentitiesOnly yes
  
...(生成した鍵の数だけ同様に記述する)
```
- `HOST`: 今回は`github-(任意の名前)`にしているが、自分がわかりやすい名前なら何でも大丈夫
- `IdentityFile` : 生成した秘密鍵のパス

ここまでの手順がうまくいっていた場合は、sshを次のように叩くと接続確認が行える。
```
$ ssh -T github-(任意の名前1)
Hi (アカウント名1)! You've successfully authenticated, but GitHub does not provide shell access.
```

本来は`git clone`等をする際にurlとして`git@github.com:(ユーザー名)/(リポジトリ名).git`と入力する。しかしConfigでHOST名とSSHキーを紐づけているため、使いたいアカウントに応じて`github-(任意の名前1):(ユーザー名)/(リポジトリ名).git`の形式に書き換える必要がある。

## 4 gitの設定
鍵の準備が終わったので、`git`でどうやって鍵を使い分けるかを設定する。
使い分け方法として次の2通りを想定した。
1. global設定を利用する
global設定でメインアカウントを設定し、サブアカウントを使いたいファイルだけ個別にlocal設定でアカウント情報を設定する方法。
メインアカウントの設定は１度で済むがlocalの設定をうっかり忘れてしまうと、サブアカウントを使うつもりがメインアカウントを使っていた、なんてことが起きかねない。
1. global設定を利用しない
global設定はせずにlocalの設定だけでgitを使う方法である。1つ目の時のようなミスは起こらないがローカルリポジトリを登録する際に毎回local設定をする必要がある。

![使い分けイメージ図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2705782/92f9dd0c-e530-56f0-0539-564c4c8414c4.png)

好きなほうをご利用ください。

### 方法1

```
$ git config --global user.name "名前1"
$ git config --global user.email "メルアド1"
$ git config --global url."github-(任意の名前1)".insteadOf "git@github.com"
```
まずglobal設定を行う。

```
$ git config --local user.name "名前n"
$ git config --local user.email "メルアドn"
$ git config --local url."github-(任意の名前n)".insteadOf "git@github.com"
```
次にlocal設定をする。
初めての`commit`の前に上のようにコマンドを叩く。

:::note warn
local設定を忘れてしまうとglobal設定を使ってしまうので注意。
:::
:::note info
```
$ git config --global url."github-(任意の名前1)".insteadOf "git@github.com"
```
をしているため、今後メインアカウントで`git clone`等をする際はurlとして`git@github.com:(ユーザー名1)/(リポジトリ名).git`と入力だけで自動的に`github-(任意の名前1):(ユーザー名)/(リポジトリ名).git`の形式に変換してくれるようになる。
しかしサブアカウントで`git clone`等をしたい際は手動で`github-(任意の名前1):(ユーザー名)/(リポジトリ名).git`の形式に書き換えないといけない。これを忘れるとメインアカウントで処理してしまう。
:::

### 方法2
```
$ git config --local user.name "名前n"
$ git config --local user.email "メルアドn"
$ git config --local url."github-(任意の名前n)".insteadOf "git@github.com"
```
global設定は何もせずに
初めての`commit`の前に1度だけ上のようにコマンドを叩く。

:::note warn
もしglobal設定にuser.nameやuser.emailが設定されているのであれば別途削除してください。
:::


# まとめ
これらの手順を進めることでSSHキーを適切に切り替えて処理してくれるようになります。