macOSのgitが別アカウントの認証を拾ってpushできない——remote URLにユーザー名を入れる
1台のMacでGitHubアカウントが複数絡むと、pushがRepository not foundで失敗する。remote URLにユーザー名が無いとgitはどのアカウントで認証するかKeychainに伝えられず、適当な1件が使われるのが原因。URLにユーザー名を入れて固定する。SSH使い分けやuseHttpPathの別解も添える。
1台の Mac で GitHub アカウントが複数絡む環境だと、push が Repository not found で失敗することがある。リポジトリもトークンも合っているのに、権限が無いように扱われる。同じ症状で詰まったので直し方を残す。
事象
git push すると remote: Repository not found で弾かれる。URL もトークンも間違っていないのに、権限が無いかのように扱われる。private リポジトリに別アカウントの認証でアクセスすると、GitHub は存在を隠すために「無い」と返すので、この見え方になる。
原因
macOS の Keychain(git がパスワードを覚えておく保管庫)は、認証情報をホスト単位(github.com)でも持つ。ここで、remote URL にユーザー名が入っていないと、git は「どのアカウントで認証するか」を Keychain に伝えられない。すると Keychain は github.com に紐づく認証の中から適当な1つ(多くは最初に登録したもの)を返す。それが目的と違うアカウントだと、権限の無いアカウントで叩くことになる。
解決策
remote URL にユーザー名を入れて、どのアカウントで認証するかを固定する。
git remote set-url origin https://USERNAME@github.com/USERNAME/REPO.git
こうすると git はそのユーザー名を Keychain に渡し、そのアカウント用の認証が引かれる。ユーザー名は秘密ではないので URL に書いて構わない。
それでも直らないときは、Keychain に古い(間違った)認証が残っている。キーチェーンアクセスで github.com のエントリを消すか、次のコマンドで消してから入れ直す。
printf 'protocol=https\nhost=github.com\n' | git credential-osxkeychain erase
別のやり方
これは HTTPS のまま最小の変更で直す手だ。ほかに、SSH 鍵をアカウントごとに使い分ける方法(~/.ssh/config の Host エイリアス)や、credential.useHttpPath を有効にしてリポジトリのパス単位で認証を分ける方法もある。アカウントを頻繁に切り替えるなら、SSH の使い分けの方が本筋なことも多い。
見分け方
git remote -v で remote URL を見て、ユーザー名(USERNAME@)が入っていないなら、まずそれを入れる。トークンは URL に生では書かない(.git/config やコマンド履歴に残る)。埋めるのはユーザー名だけにする。