こんにちは。
複数GitHubアカウントをディレクトリごとに自動で切り替える運用方法が固まってきたので既出感ありますが、備忘録として残しておきます。
文中のprivateusername
などのメールアドレス、ユーザー名等は適宜任意のものに読みかえて下さい。
背景
業務時は仕事用GitHubアカウントを使っています。
しかしdotfilesだけ個人アカウントのものを使い回したくて、個人用GitHubアカウントにもfetch/pushできるようにしたかったのでいくつか設定しました。
どういうことができるようになるか
1. ディレクトリに応じた自動アカウント切り替え
設定後、作業ディレクトリが~/github/
以下であれば個人用のGitHubアカウント(private)、それ以外のディレクトリでは会社用のGitHubアカウント(company)が自動的に使用されます。
これにより、リポジトリごとに手動でアカウントを切り替える必要がなくなります。
実行例: 個人用ディレクトリでの操作
# 個人用ディレクトリに移動
cd ~/github/my-personal-repo
# ディレクトリでリポジトリを自動判別して適切な認証をする
git add .
git commit -m "個人用ディレクトリでの操作は個人用GitHubアカウントSSHキーと紐づくよう設定"
git push
# リポジトリのクローン
# `git clone git@private:privateusername/my-personal-repo.git`が実行される
gitclone git@github.com:privateusername/my-personal-repo.git
2. クローン時の自動切り替え
新しくリポジトリをクローンする際も、シェルスクリプトを使用することで、ディレクトリに応じて自動的にホストエイリアスが適用されます。
実行例: 個人用ディレクトリでの新規リポジトリクローン
# 個人用ディレクトリに移動
cd ~/github/
# リポジトリのクローン
# `git clone git@github.com:privateusername/new-private-repo.git`が実行される
gitclone git@github.com:privateusername/new-private-repo.git
設定方法
方針としては、まず~/.gitconfig
でディレクトリごとのホストを設定します。
次に~/.ssh/config
でホスト名とSSHキーのパスを紐づけます。
GitHubアカウントはSSHキーによって認証されるので、これによってディレクトリごとに異なるGitHubアカウントを使えるようになります。
ちなみにホストとはドメイン名やIPアドレスのことで、今回はデフォルトホスト名がgithub.com
ですがSSHキーとの紐づけを切り替えるためにホストエイリアスを使用しています。
1. SSH設定の準備
まず、個人用と会社用のSSHキーをそれぞれ生成し、GitHubアカウントに登録します。
既にキーを生成している場合はディレクトリを移動させるだけで大丈夫です。
ドキュメント通りに設定していると~/.ssh/
配下に~/.ssh/id_rsa
, ~/.ssh/id_rsa.pub
があると思いますのでそれを移動させてください。
# 会社用SSHキーの生成
ssh-keygen -t ed25519 -C "your_company_email@example.com" -f ~/.ssh/company
# 個人用SSHキーの生成
ssh-keygen -t ed25519 -C "your_private_email@example.com" -f ~/.ssh/private
新規に生成した場合は生成された公開鍵 (~/.ssh/company.pub と ~/.ssh/private.pub) を、それぞれのGitHubアカウントのSSHキー設定にウェブページ上から追加します。
2. SSH設定ファイルの編集
次に、~/.ssh/config
ファイルを編集して、ホストエイリアスを定義します。これにより、特定のエイリアスを使用して異なるSSHキーを自動的に選択できます。
# ~/.ssh/config
# 会社用GitHubアカウント
Host company
HostName github.com
User git
IdentityFile ~/.ssh/company
Port 22
TCPKeepAlive yes
IdentitiesOnly yes
AddKeysToAgent yes
# 個人用GitHubアカウント
Host private
HostName github.com
User git
IdentityFile ~/.ssh/private
Port 22
TCPKeepAlive yes
IdentitiesOnly yes
AddKeysToAgent yes
3. Git設定ファイルの編集
Gitの設定ファイル (~/.gitconfig
) を編集して、条件付きインクルードを利用し、ディレクトリごとに異なる設定ファイルを読み込むようにします。
# ~/.gitconfig
[user]
name = companyusername
email = your_company_email@example.com
[credential "https://github.com"]
useHttpPath = true
[url "git@company:"]
insteadOf = git@github.com:
[includeIf "gitdir:~/github/**"]
path = ~/.gitconfig_private
個人用Git設定ファイルの作成
~/.gitconfig_private
ファイルを作成し、個人用の設定を追加します。
# ~/.gitconfig_private
[user]
name = privatename
email = your_private_email@example.com
[url "git@private:"]
insteadOf = git@github.com:
4. GitリモートURLの設定
既存のリポジトリのリモートURLを、ホストエイリアスを使用するように変更します。
git remote -v
した結果が既に下記のようになっていれば不要です。
会社用リポジトリの場合
cd /path/to/company-repo
git remote set-url origin git@company:companyusername/company-repo.git
個人用リポジトリの場合
cd ~/github/private-repo
git remote set-url origin git@private:privateusername/private-repo.git
5. SSHエージェントの設定
SSHエージェントにSSHキーを追加します。これにより、パスフレーズの入力を省略できます。
# SSHエージェントの起動
eval "$(ssh-agent -s)"
# 会社用SSHキーの追加
ssh-add ~/.ssh/company
# 個人用SSHキーの追加
ssh-add ~/.ssh/private
git clone
git cloneコマンドだけは自動で切り替えてくれず、通常GitHubページ上でコピーしたURLはgit@github.com:~~
という形式ですがgit@company:~~
のように書き換えなければならず面倒です。
そこで今回はシェルスクリプトを書いて対応しました。
function git_clone_auto() {
local repo_url="$1"
local host_alias="company" # デフォルトは 'company'
# ホストエイリアスの決定
case "$PWD" in
"$HOME"/github/**)
host_alias="private"
;;
esac
if [[ "$repo_url" == git@github.com:* ]]; then
local repo_path="${repo_url#git@github.com:}"
echo "実行コマンド: git clone git@${host_alias}:${repo_path}"
git clone "git@${host_alias}:${repo_path}"
else
echo "実行コマンド: git clone $repo_url"
git clone "$repo_url"
fi
}
alias gitclone='git_clone_auto'
$ gitclone git@github.com:~~~/~~~~~.git
これでコピーしたURLをそのまま使えます。
確認
設定が正しく動作しているか確認します。
1. SSH接続の確認
それぞれのホストエイリアスを使用して、GitHubとのSSH接続が正しく行われているか確認します。
# 会社用アカウントの確認
$ ssh -T git@company
Hi companyusername! You've successfully authenticated, but GitHub does not provide shell access.
# 個人用アカウントの確認
$ ssh -T git@private
Hi your-private-username! You've successfully authenticated, but GitHub does not provide shell access.
2. リモートURLの確認
各リポジトリのリモートURLが正しく設定されているか確認します。
$ cd /path/to/repository
$ git remote -v
origin git@company:companyusername/company-repo.git (fetch)
origin git@company:companyusername/company-repo.git (push)
# または
origin git@private:privateusername/private-repo.git (fetch)
origin git@private:privateusername/private-repo.git (push)
3. git push のテスト
各リポジトリからのgit pushが正しく動作するか確認します。
cd /path/to/repository
git push origin main
エラーが発生せず、正しいアカウントにプッシュされることを確認します。
4. gitcloneシェルスクリプト の動作確認
新規リポジトリをクローンする際に、シェルスクリプトが正しくホストエイリアスを適用しているか確認します。
# 個人用ディレクトリでのクローン
cd ~/github/
gitclone git@github.com:privateusername/new-private-repo.git
# 会社用ディレクトリでのクローン
cd ~/work/
gitclone git@github.com:companyusername/new-company-repo.git
まとめ
そもそも一つのアカウントで運用しろという声も聞こえてきますが、複数アカウント使うならこんな感じでしょう。
もう一つ罠があるとすればGitHubのCLIツールgh
コマンドは今回対応していないので、gh
コマンド仕様の際はgh switch
でアカウントを切り替えて使うようにしています。
それでは✋️