🍦

Git/GitHub 複数アカウントを手軽に切り替えるための設定方法

に公開
2

いろいろな事情から1人で複数のGitユーザー名、GitHubの認証情報を使わないといけないことがあり、手軽に切り替えて安全に運用できる設定方法を探し求めていました。今まで事故らないためパソコン自体分けるという富豪対策をしていたのですが、やはり困ることも出てくるので1台のPC内で実現する方法を調べて試してまとめました。

ポイントとしては、極力手軽かつ、間違えを減らす運用ができるところです。具体的には以下です。

  • gh(GitHub CLI)を使用する前提。ログイン情報もghの認証情報を使用
  • 常に今のGitのユーザー情報・GitHubの認証情報をプロンプトに表示して事故防止
  • リポジトリごとにコマンド1発でローカルのGitのユーザー情報とGitHubの認証情報を設定
  • 1度設定されたリポジトリに移動すると、自動でGitのユーザー情報・GitHubの認証情報が設定される
  • Gitのグローバル設定は使用しないで運用することも、コマンド一発で設定・切り替えも可能

GitHubの認証に関しては、大きくわけるとトークン(PAT)方式とSSH鍵認証の2つがあるのですが、Gitのcredential helperにghを登録することで、Macの場合はデフォルトでセキュアにトークン方式でアクセスすることができます。LinuxやWindows(WSL2)でも同様の設定が可能ですが、認証情報の扱いに少し違いあるので、注記を記載しています。

SSH鍵については本記事では扱いません。

事前設定

ghのインストールとログイン

まずはgh(GitHub CLI)をインストールします。

Macの場合はHomebrewをセットアップしたあと、以下コマンド実行します。

$ brew install gh

Linuxの場合は以下コマンド実行することでインストールできます。ただ、Linuxの環境(自分の場合はUbuntu)によってはバージョンが古い場合があるので注意が必要です。

$ sudo apt update
$ sudo apt install gh

バージョンが古い場合はsnapでインストールするのが手軽です。GitHub 公式リポジトリを追加して apt installする方法もありますが、本記事では省略します。

$ sudo apt remove gh
$ sudo snap install gh

バージョンを確認します。

$ gh --version

バージョンは最低2.6.0以上が必要です。今回はmacOSで2.78.0、Linuxで2.74.0で実施しました。ghのユーザー切り替えに関して--profileはv2.3〜2.5系でサポート、--userはv2.6以降で利用可能と互換性がありません。この記事では--userを前提に記載しているので、注意してください。

続いて、GitHubの認証のためのログインをします。複数アカウントある場合は、それぞれのアカウントで複数回ログインします。

$ gh auth login

以下コマンドで設定情報と今アクティブなユーザが分かります。

$ gh auth status -h github.com
github.com
  ✓ Logged in to github.com account UserA
  - Active account: true
  - Git operations protocol: https
  - Token: gho_************************************
  - Token scopes: 'gist', 'read:org', 'repo', 'workflow'

  ✓ Logged in to github.com account UserB
  - Active account: false
  - Git operations protocol: https
  - Token: gho_************************************
  - Token scopes: 'gist', 'read:org', 'repo', 'workflow'

ユーザーを切り替えたい場合は以下コマンドで手動で切り替えられます。

$ gh auth switch

ユーザーを指定して切り替える場合は、以下コマンドで切り替えられます。

$ gh auth switch --user <GitHubアカウント名>

参考:GitHub CLI で複数のアカウントを簡単にスイッチ可能になりました

Gitのcredential helperにghを登録

以下コマンドでGitのcredential helperにghを登録します(冒頭に紹介した設定です)。

$ gh auth setup-git

上記コマンドでは、具体的には~/.gitconfigに以下のような設定を書き込むことになります(ghのパスは、環境により異なります)。

[credential "https://github.com"]
        helper = 
        helper = !/path/to/gh auth git-credential
[credential "https://gist.github.com"]
        helper = 
        helper = !/path/to/gh auth git-credential

認証情報は、Macの場合はデフォルトでmacOS Keychainに保存されてセキュアですが、LinuxやWindows(WSL2)の場合は~/.config/gh/hosts.yml等に平文で保存されるようです(保存される場所はgh auth statusコマンドで確認できます)。

chmod 600 ~/.config/gh/hosts.ymlで権限絞ったり、どうしても気になる方は、別の方法でよりセキュアな運用をするようにしてください。

.netrcの設定

本記事では使用しない方法ですが、GitHubの認証情報のトークン方式での手軽な設定方法として~/.netrcというファイルに以下のように記載する方法もあります。usernameaccesstokenには、自分のGitHubのアカウント名とアクセストークンを入れると設定できます。

machine github.com
login username
password accesstoken

先ほど説明したghでの認証情報設定と.netrcの設定を両方していると、設定が干渉してしまいGit操作ができない場合があるので、こういう方法があるよということで紹介しておきます(自分は設定しているの忘れててハマりました)。

本記事の設定を使用する場合は.netrcをバックアップファイルとして退避するか(mv ~/.netrc ~/.netrc.bak等)、.netrcのGitHubの設定を削除するなどしてください(.netrcはGitHub以外の設定にも使う場合があります)。

シェルログイン時の切り替え設定

ログインシェルに以下のような設定を追記します。これにより、以下のことが可能となります。

  • 今いるリポジトリのGit/gh(GitHub)の設定をプロンプトに表示
  • コマンドで今いるリポジトリのGit/gh(GitHub)の設定を変更

以下は.zshrcに追記する設定です。macOSの場合はこれがよいと思います。最初の2行だけ、自分のアカウント情報を編集してください。

# ←ここをあなたの情報に置き換え
GH_USER_A="<GitHubアカウント名 A>"   ; GH_NAME_A="<ユーザー名 A>" ; GH_MAIL_A="<メールアドレス A>"
GH_USER_B="<GitHubアカウント名 B>"   ; GH_NAME_B="<ユーザー名 B>" ; GH_MAIL_B="<メールアドレス B>"


# プロンプト用キャッシュ(起動直後は常に "-")
GH_USER_PROMPT="-"
GIT_USER_PROMPT="-"

# プロンプトでコマンド展開を有効化
setopt PROMPT_SUBST
PROMPT='%F{green}[%~]%f <${GIT_USER_PROMPT}|${GH_USER_PROMPT}> %# '

# 今が Git リポなら --local、-g なら --global に設定
_git_set_identity_maybe_global() {
  local nm="$1" mail="$2" who="$3" gflag="$4"
  if [[ "$gflag" == "-g" ]]; then
    git config --global user.name  "$nm"
    git config --global user.email "$mail"
    # gh.user は global には書かない
  else
    if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
      git config --local user.name  "$nm"
      git config --local user.email "$mail"
      git config --local gh.user    "$who"
    else
      echo "(info) Gitリポ外なので --global 以外では user.* は変更しません。"
    fi
  fi
}

# ディレクトリ移動時にプロンプト用キャッシュを更新
chpwd() {
  if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    # 左(git user.name)
    GIT_USER_PROMPT="${$(git config --get user.name 2>/dev/null):-"-"}"

    # 右(gh user)
    local want; want="$(git config --get gh.user 2>/dev/null)"
    if [[ -n "$want" ]]; then
      gh auth switch --user "$want" -h github.com >/dev/null 2>&1 && export GH_USER="$want"
      GH_USER_PROMPT="$want"
    else
      GH_USER_PROMPT="-"
    fi
  else
    GIT_USER_PROMPT="-"
    GH_USER_PROMPT="-"
  fi
}

# メインに切替(-g で global も可)
gitmain() {
  local gflag="${1:-}"
  gh auth switch --user "$GH_USER_A" -h github.com || return 1
  export GH_USER="$GH_USER_A"
  _git_set_identity_maybe_global "$GH_NAME_A" "$GH_MAIL_A" "$GH_USER_A" "$gflag"
  echo "Switched: gh->$GH_USER  git(${gflag:--local}): $GH_NAME_A <$GH_MAIL_A>"
}

# サブに切替
gitsub() {
  local gflag="${1:-}"
  gh auth switch --user "$GH_USER_B" -h github.com || return 1
  export GH_USER="$GH_USER_B"
  _git_set_identity_maybe_global "$GH_NAME_B" "$GH_MAIL_B" "$GH_USER_B" "$gflag"
  echo "Switched: gh->$GH_USER  git(${gflag:--local}): $GH_NAME_B <$GH_MAIL_B>"
}

# 状態確認(必要な時だけ gh api を使う)
gitwho() {
  local cur; cur="$(gh api user -q .login 2>/dev/null || echo "-")"
  echo "gh : ${cur} (env:${GH_USER:-"-"})"
  if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    echo "git: $(git config --get user.name) <$(git config --get user.email)>"
  else
    echo "git: (not in a repo)"
  fi
}

############################################
# ここまで
############################################

以下はbashrcの設定です。Linux(Ubuntu)などを使用している人用です。以下トグルを開いて表示してください。

bashrcの設定
############################################
# Git × gh 複数アカウント運用(bash版)
############################################

# ←あなたのGitHubログイン名/著者名/メールに置き換え
GH_USER_A="<GitHubアカウント名 A>";     GH_NAME_A="<ユーザー名 A>";        GH_MAIL_A="<メールアドレス A>"
GH_USER_B="<GitHubアカウント名 B>"; GH_NAME_B="<ユーザー名 B>;   GH_MAIL_B="<メールアドレス B>"

# プロンプト用キャッシュ(起動直後は常に "-")
export GH_USER_PROMPT="-"
export GIT_USER_PROMPT="-"

# 色(bash)
GREEN="\[\e[32m\]"
RESET="\[\e[0m\]"

# PS1(左にカレント、<>に 著者|ghユーザー)
export PS1="${GREEN}[\w]${RESET} <\${GIT_USER_PROMPT}|\${GH_USER_PROMPT}> \\$ "

# 今がGitリポなら --local のみ更新(gh.user も local に記録)
_git_set_identity() {
  local nm="$1" mail="$2" who="$3" scope="local"
  if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    git config --local  user.name  "$nm"
    git config --local  user.email "$mail"
    git config --local  gh.user    "$who"
  else
    echo "(info) Gitリポ外です。global を変えたいときは -g を付けてください。"
    return 1
  fi
}

# (任意)global を切り替えたいとき用: gitmain -g / gitsub -g
_git_set_identity_maybe_global() {
  local nm="$1" mail="$2" who="$3" gflag="$4"
  if [[ "$gflag" == "-g" ]]; then
    git config --global user.name  "$nm"
    git config --global user.email "$mail"
    # gh.user は global には書かない(混乱防止)
  else
    _git_set_identity "$nm" "$mail" "$who" || return 1
  fi
}

# 右側(gh)をネットワークなしで切替&反映
__gh_switch_to() {
  local want="$1"
  gh auth switch --user "$want" -h github.com >/dev/null 2>&1 && export GH_USER="$want"
  export GH_USER_PROMPT="$want"
}

# 左右のプロンプト用キャッシュを更新(速い)
__refresh_prompt_cache() {
  if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    local nm; nm="$(git config --get user.name 2>/dev/null)"
    [[ -n "$nm" ]] && export GIT_USER_PROMPT="$nm" || export GIT_USER_PROMPT="-"

    local want; want="$(git config --get gh.user 2>/dev/null)"
    if [[ -n "$want" ]]; then
      # gh は want に揃える(ローカル切替なので軽い)
      __gh_switch_to "$want"
    else
      export GH_USER_PROMPT="-"
    fi
  else
    export GIT_USER_PROMPT="-"
    export GH_USER_PROMPT="-"
  fi
}

# ディレクトリ変更検知(bashは chpwd がないのでPROMPT_COMMANDで実装)
__LAST_PWD=""
__on_prompt() {
  if [[ "$__LAST_PWD" != "$PWD" ]]; then
    __LAST_PWD="$PWD"
    __refresh_prompt_cache
  fi
}
# 既存の PROMPT_COMMAND を壊さないように連結
if [[ -n "$PROMPT_COMMAND" ]]; then
  PROMPT_COMMAND="__on_prompt; $PROMPT_COMMAND"
else
  PROMPT_COMMAND="__on_prompt"
fi

# メイン/サブ切替(-g で global 著者に切替も可)
gitmain() {
  local gflag="${1:-}"
  gh auth switch --user "$GH_USER_A" -h github.com || return 1
  export GH_USER="$GH_USER_A"
  _git_set_identity_maybe_global "$GH_NAME_A" "$GH_MAIL_A" "$GH_USER_A" "$gflag" || return 1
  __refresh_prompt_cache
  echo "Switched: gh->$GH_USER  git(${gflag:--local}): $GH_NAME_A <$GH_MAIL_A>"
}
gitsub() {
  local gflag="${1:-}"
  gh auth switch --user "$GH_USER_B" -h github.com || return 1
  export GH_USER="$GH_USER_B"
  _git_set_identity_maybe_global "$GH_NAME_B" "$GH_MAIL_B" "$GH_USER_B" "$gflag" || return 1
  __refresh_prompt_cache
  echo "Switched: gh->$GH_USER  git(${gflag:--local}): $GH_NAME_B <$GH_MAIL_B>"
}

# 状態確認(必要時だけAPI使用:遅くなるので常用しない)
gitwho() {
  local cur; cur="$(gh api user -q .login 2>/dev/null || echo "-")"
  echo "gh : ${cur} (env:${GH_USER:-"-"})"
  if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
    echo "git: $(git config --get user.name) <$(git config --get user.email)>"
  else
    echo "git: (not in a repo)"
  fi
}

############################################
# ここまで
############################################

使用方法

本記事では、以下2つの運用方法を説明します。

  • リポジトリごとのローカル設定のみを使用
  • グローバル設定も使用する方法

ローカル設定のみの方が運用上安全(間違ったアカウントでGit操作してしまうリスクを減らせる)ですが、グローバル設定を用いると、操作を簡略化できたりして便利です。自分の使い方に合わせて使用してください。順に説明いたします。

リポジトリごとのローカル設定のみを使用

Gitのグローバルの設定(~/.gitconfig)を使わない運用方法です。

最初に以下コマンドでGitのグローバルの設定(~/.gitconfig)からユーザー名とメールアドレスを消しておきます。これは最初にやればOKです。

$ git config --global --unset user.name
$ git config --global --unset user.email

ターミナル起動直後、リポジトリ外(例:ホームディレクトリ)では、プロンプトは [~] <-|->と表示されます。右側(gh側)は、そのリポジトリにgh.userが設定されているとき だけアカウント名に変わります。リポジトリ外では常に-のままです。

リポジトリをクローンするときは、publicなリポジトリならgit cloneでよいですが、プライベートなリポジトリの場合は、ghコマンドを使います。以下ghコマンドで権限のあるアカウントに変更します。

[~] <-|-> % gh auth switch

本記事で設定したgitwhoコマンドで ghとgitの設定情報を確認できます。

[~] <-|-> % gitwho
gh : <GitHubアカウント名> (env:-)
git: (not in a repo)

ghでcloneします。

[~] <-|-> % gh repo clone <git url>

リポジトリに入ってGit/GitHubの設定をします。

[~] <-|-> % cd repo-a
[~/repoA] <-|-> % gitmain

Gitのユーザー情報が即時設定されて、GitHubの認証情報が切り替えられます。プロンプトの表示も切り替わります。

[~/repoA] < Gitユーザー名| GitHubアカウント名 > %

設定されてないディレクトリに移動すると、設定が即時に切り替わり、プロンプトに表示されます。

[~/repoA] < Gitユーザー名| GitHubアカウント名 > % cd
[~] <-|-> %

あとはこれをリポジトリごとにユーザーに合わせてgitmain, gitsubを設定するだけです。設定はリポジトリごとに一回やれば、あとはリポジトリに移動するだけで設定が自動で反映されます。

グローバル設定も使用

ローカル設定だけだと、プライベートリポジトリのgit cloneが手間、操作をするリポジトリ全てで(1回だけとはいえ)、コマンドでGit/GitHubの設定が必要となります。

この手間を削減するために、グローバル設定もしたいという場合は、以下オプションで手軽にグローバル設定できます。

$ gitmain -g # メインアカウントをグローバル設定
$ gitsub -g # サブアカウントをグローバル設定

プライベートなリポジトリをgit cloneでダウンロードしたい場合は、上記のグローバル設定で対象のアカウントに切り替えればOKです。また、ローカル設定されてないリポジトリでは、グローバル設定が適用されるので、その設定でGitの操作が可能です。

ただ、デメリットとして、想定と異なるアカウントでコミット等のGit操作をしてしまうリスクがあるので、その点は気をつけるようにしましょう。

まとめ

Gitのユーザー名、GitHubの認証情報を手軽に切り替える方法についてまとめました。ずっとやりたかったのにめんどくさくてサボっていましたが、ようやく自分にとってベストプラクティスに近い方法をまとめられた気がします。

似たようなことをやっている人の記事を参考にしたり、AIに聞いたらすぐできるかなと思いましたが、自分の環境にピッタリなのがなかったり、以前Gitアカウント間違えてコミットしてリポジトリ作り直すことになった苦い経験から慎重になっていたため、、色々調べていたらすごい時間かかってしまいました。自分がポンコツなのもありますが…

この記事が、似たようなことで困っている誰かの役に立つとよいなと思っています。

関連記事

https://zenn.dev/karaage0703/articles/a1ee72f22882e9

https://zenn.dev/karaage0703/articles/d90c18f65921fc

変更履歴

  • 2025/08/25 誤記訂正・小修正

Discussion

Hiroshi KoyamaHiroshi Koyama

gh コマンドによる認証情報を使いまわすアイデアが面白いと思いながら拝読させていただきました。自分は SSH エージェント派です。あと、自分は、Git のユーザー情報については、Git のグローバルの設定で指定すると事故がおきるので、リポジトリ単位に指定するようにしています。

本文の誤字と思われるものがあったので、お知らせしておきます。

  • Ubunutの環境Ubuntuの環境 でしょうか。
  • ずっとやりけどずっとやりたかったけど でしょうか。
  • 何箇所か 、、 という区切りがあり、気になりました。
からあげからあげ

コメントありがとうございます。誤記訂正いたしました。WebにはSSH鍵認証記事が多かったのですが、自分はghを使うのでせっかくならその認証情報使いたいなと思い記事書きました。Gitのリポジトリ設定とグローバル設定は、便利さとリスクのトレードオフですね。今回は併記という形にしました。