https時代のgitアカウントを使い分ける方法のメモ

時代はhttps

f:id:hitonatsu:20181027101737p:plain

https://help.github.com/articles/set-up-git/

  • GitHubではhttps推奨になっているし…
  • httpsのほうがclone速度はやいし…
  • まとめに書くけどhttpsにすると覚えることが1個だけでラク

SSHでアカウントを使い分けるときはどうしていたか

~/.ssh/configを作成して

host github.com-main
 HostName github.com
 IdentityFile ~/.ssh/id_rsa_github
 User git

host github.com-sub
 HostName github.com
 IdentityFile ~/.ssh/id_rsa_github_sub
 User git

みたいなことを書いてssh-add -K ~/.ssh/id_rsa_githubして

$ git clone git@github.com-main:username/repo.git

形式でcloneしたりしていた。git@github.com-mainとかgit@github.com-subとか長いし憶えられないしでつらい。アカウントの数が増えるたびにconfigに足す設計になるのもつらい気がする。

あるいは

$ GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa_example -F /dev/null" git clone example

Git環境変数にGIT_SSH_COMMANDが生えてからこうもできていたけどコマンド長いし憶えられないし毎回鍵のパスいるしでつらい気がする。

git2.1.0以降は.gitconfigで管理できるようになって

$ git config core.sshCommand "ssh -i ~/.ssh/id_rsa_example -F /dev/null"

で鍵指定したりできるようになって便利、だけどそもそもローカルの.gitconfigが必要になってきてちょっぴりつらい。


superuser.com

まあSSHでのアカウント切り替えはstackexchangeのこのスレッドが一番まとまっていると思っている

Caveat

  • 個人的なメモで書いているので多分に間違ってたりするかもしれない

  • ssh-keygenしてからのはなしなのでキージェネレーションのやりかたは書かない

  • ひとつのマシンでgitアカウントを使い分けたい

  • 筆者はMacOS環境なのでMacOS前提で書かれています

そもそもコミッター情報(コミッター名とメアド)はどこに依存しているか

gitのコミッター名とメアドは.gitconfig、あるいはGitの環境変数に依存する

なのでコミットログに記録されるアカウントを切り替えるなら

.gitconfigの場合

$ git config --global user.name "Mona Lisa"
$ git config --global user.email "email@example.com"

グローバルの.gitconfigにコミッター名とメアドを設定。

ローカル(リポジトリ単位のスコープ)で設定するなら

$ git config --local user.name "Mona Lisa"
$ git config --local user.email "email@example.com"

でOK。

環境変数で切り替えるなら

export GIT_COMMITTER_NAME="Mona Lisa"
export GIT_COMMITTER_EMAIL="email@example.com"
export GIT_AUTHOR_NAME="Mona Lisa"
export GIT_AUTHOR_EMAIL="email@example.com"

という具合にする。

環境変数を実際にリポジトリごとに切り替えたりする場合には、direnvを使うと自分は便利だと思っている。

direnvを使う方法はこちらのブログがすごくわかりやすい。


ようするにコミッターを切り替えるための情報を.gitconfigで管理したいなら、使いたいアカウントのnameとemailを.gitconfigに書けばOK。この場合globalとlocalの.gitconfigを巧みに使いわけることになる。

あるいはGit環境変数で管理したいなら、.envrcなりに環境変数をよしなに設定していく。

なおこれらコミッター名の切り替えに関しては以前書いたこの辺の話にも通ずる。

tech-1natsu.hatenablog.com

認証まわりを使い分ける…プライベートリポジトリもcloneしたりpushしたい!

git addするときのコミッター情報を切り替えるのは上記の方法でOKだけど、git pushなりgit cloneするときの認証の場面では上の設定は関係ない。

関係ないとは言っても普通にパブリックリポジトリをCloneする場合は

$ git clone https://gitlab.com/1natsu172/example-public-repo.git

でクローンできる。

プライベートリポジトリでもCloneするなら

$ git clone https://gitlab.com/1natsu172/example-private-repo.git
Username for 'https://gitlab.com': 
Password for 'https://gitlab.com':

という具合にリポジトリへのアクセス権を持ってるか聞かれるので正しいアカウント情報を打てばCloneできる。

毎回使いたいほうのアカウント名とパスワードを打てばアカウントを使い分けられますね。めでたしめでたし。

……めでたしなわけがない。毎回毎回パスワードを打つなんて人間のすることじゃない。

ユーザー名とパスワードをcredential helperに記憶してもらう

人間が毎回打つのは勘弁してほしい。なので記憶してもらうようにする。

MacOSの場合はGit自体に付属しているosxkeychain helperにお願いする。

$ git config --global credential.helper osxkeychain

これでglobalの.gitconfigosxkeychain helperを使うように書き込まれて、めでたく毎回パスワードを打たなくてよくなりました。


なおそもそもgit credential-osxkeychainが使えるかを確認したいなら、

$ git credential-osxkeychain

Usage: git credential-osxkeychain <get|store|erase>

こう返ってくればOKなよう。

上記のcredential helperことは実は全部Githubのヘルプに書かれている。

ところでこれでどうやって認証アカウントを切り替えるんですか?

『パスワード記憶してくれるようになったのはいいけど、どっちのアカウントで認証するかを指示してないじゃないか、プライベートリポジトリのアクセスはどうやって切り替えるんだ!』

わかります。

httpsではプライベートリポジトリのcloneをするときはこう。

https://<username>@<domain>/<repository-username>/<repository-name>.git

ドメインの前に「ユーザー名@」をつける

つまりgit cloneするときにこう

$ git clone https://hitonatsu@gitlab.com/1natsu172/example-private-repo.git

ユーザー名がhitonatsuのアカウントを使いたい場合の例

すると初回だけ

$ git clone https://hitonatsu@gitlab.com/1natsu172/example-private-repo.git
Password for 'https://hitonatsu@gitlab.com':

のようにパスワードを聞かれて、以降はcredential helperが憶えてくれる。

つまり初回のみでOK

リポジトリhttps形式のURLをブラウザからゲットしようとすると

f:id:hitonatsu:20181027084203p:plain

これはGitHubですが…

まあこういう感じ。

リポジトリを最初にcloneするときだけこれをコピーして

https://<username>@<domain>/~

形式に変えてcloneするだけでOK。以後は各アカウント毎にパスワードを憶えてくれる。

「ユーザー名@」をつけてcloneするとリポジトリのリモートURLはどうなるかというと

$ git remote -v
origin  https://hitonatsu@gitlab.com/1natsu172/example-private-repo.git (fetch)
origin  https://hitonatsu@gitlab.com/1natsu172/example-private-repo.git (push)

でちゃんと設定される。

既存のローカルリポジトリのリモートURLをこの形式に変えるなら普通にgit remote set-url origin {url}てな具合で普通にすればOKなはず。

credential helperhttps://<username>@<domain>ごとに記憶してURL判断してくれるっぽいので、これでうまくアカウントを切り替えられた。


ちなみにお察しの通りMacOSではキーチェーンアクセスに保存される。

f:id:hitonatsu:20181027082737p:plain

GitHubじゃなくGitLabの例ですがちゃんとアカウント2件分保存されてますね

まとめ

だけ!

1回設定すればOK、プライベートリポジトリも「ユーザー名@」つけてcloneするだけで完全にラク。覚えやすい。


ハマり解決情報

GitHub Help 最強
  • ぶっちゃけGitのことでハマったらたいていGitHubのヘルプを見ればわかる
    • 検索しづらい見づらいですが…
  • Set up gitに沿って設定すればだいたいなんでもうまくいく
Q. リモートリポジトリとやりとりするときパスワード入れてもうまくいかない…

A.もしかして:2段階認証(2FA)

2段階認証(2FA)してるならcli上で聞かれるパスワード欄には生成したpersonal access tokenを入れる。