Jaybanuan's Blog

どうせまた調べるハメになることをメモしていくブログ

複数のGitのユーザを使い分ける

はじめに

複数のGitサーバ/サービスを利用する場合、Gitのユーザの切り替えが必要になる。 適切に切り替えを行わないと、誤ったユーザでコミットしてしまって、履歴を汚してしまう。 できるだけこの失敗を防ぐために、やっていることのメモを残しておく。

ユーザをグローバルに設定しない

あえてグローバルにユーザを設定せず、リポジトリごとにローカルにユーザを設定する。 これで、「デフォルト(=グローバルな設定)のユーザでコミットしてしまった」というミスは防げる。

示すまでもないが、各リポジトリ内で以下を設定することになる。

$ git config --local user.name "jaybanuan"
$ git config --local user.email ”jaybanuan@example.com”

Bashのプロンプトにユーザ名を表示する

カレントディレクトリのリポジトリにどのユーザが設定されているかを、Bashのプロンプトに表示しておく。 これで、「想定とは違うユーザでコミットしてしまった」というミスを減らすことができる。

やりたいことを具体的に説明すると、通常は以下のようなプロンプトだが、

jaybanuan@devpc:~/src $ 

以下のようにgit cloneしたリポジトリに移動すると、

jaybanuan@devpc:~/src $ git clone https://host/path/to/myapp.git
jaybanuan@devpc:~/src $ cd myapp

以下のように、末尾にgitのユーザ名@ブランチ名が付加されたプロンプトに変える。

jaybanuan@devpc:~/src/myapp (jaybanuan@main)$

ユーザ名が設定されていない場合は以下のようにNO-USER-NAMEと表示し、git configでユーザ名を設定すると上記と同様にユーザ名が表示されるようになる。

jaybanuan@devpc:~/src/myapp (NO-USER-NAME@main)$
jaybanuan@devpc:~/src/myapp (NO-USER-NAME@main)$ git config --local user.name jaybanuan
jaybanuan@devpc:~/src/myapp (jaybanuan@main)$

これを実現するために、以下のスクリプトを"~/.bashrc"に付け加えておく。

get_git_info_for_ps1() {
    local GIT_INFO=$(__git_ps1 "%s")
    if [ -n "$GIT_INFO" ]; then
        local GIT_USER_NAME=$(git config --get user.name)
        if [ -z "$GIT_USER_NAME" ]; then
            USERNAME="NO-USER-NAME"            
        fi
        
        echo " ($USERNAME@$GIT_INFO)"
    fi
}

PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\#033[00m\]\[\033[36m\]$(get_git_info_for_ps1)\[\033[00m\]\$ '

複数のユーザを管理できるCredential Helperを使う

gitのパスワード管理にはCredential Helperを利用すると入力の手間が省けて楽である。 しかしながら、Credential Helperの設計思想的には、ある1人のユーザが複数のGitサーバを使い分けるという一対多の関係を想定していると思われる。 現実にはプロジェクトやポジションによってユーザを使い分けることがあり、その場合は多対多の関係になる。

サードパーティ製(GitHub製)のCredential Helperにgit-credential-manager-coreというものがあり、名前空間という独自機能をもっている。 この名前空間を利用してユーザごとに管理領域を分けることで、多対多の管理を実現することができる。

github.com

具体的には、git-credential-manager-coreをインストールした後、cloneしたgitのリポジトリに入って以下のようなコマンドを実行すれば良い。

$ git config --local credential.credentialStore secretservice
$ git config --local credential.namespace jaybanuan

参考

リポジトリをcloneするたびに適切にgit configを実行するのが面倒だったので、スクリプト化した。

github.com

スクリプトはgitのサブコマンドの仕様に沿ったファイル名にしてあるので、パスの通っているディレクトリに配置しておけば、以下のように1コマンドで設定ができる。

$ git user jaybanuan