Plan 9とGo言語のブログ

主にPlan 9やGo言語の日々気づいたことを書きます。

GitのリモートURL単位でuser.nameとuser.emailを強制する

この記事はQiitaで公開されていました

困ったこと

GitHubは、コミットログのアイコン表示などで、Authorのメールアドレスを使います。なので、例えば普段とは違うマシンからコミットした場合、Authorのメールアドレスが普段と異なる場合は、アイコンが表示されません。

私自身は、業務ではGitHub Enterpriseを使っていて、GitHub Enterpriseには会社のアカウントでログインしています。しかし当然ですがGitHubも使ってまして、こちらのアカウントはGitHub Enterpriseとは異なります。

Cloneするリポジトリの数は圧倒的にGitHubの方が多いので、~/.gitconfigGitHub側のアカウントを書いていますが、これではGitHub EnterpriseのリポジトリGitHub側のアカウントが使われてしまいます。そのままコミットしてもエラーにはならないので、自分で管理しておかなければいけません。

例えば~/.gitconfigにはこのように書いておいて、

[user]
  name = lufia
  email = lufia@example.org

GitHub Enterpriseのリポジトリには個別に設定する。

$ git config user.name user1
$ git config user.email user1@example.com

今まではこれで運用していましたが、面倒だし、忘れた時に気付かなくて困ります。

対策

~/.gitconfigのデフォルトを削除する

コミット時に警告が表示されるので気がづく、という方法です。リポジトリごとにuser.nameやuser.emailの設定を強制するという記事があります。

ですが、間違えはないけど面倒だと思って、この方法は使いませんでした。また、勝手に~/.gitconfigを書き換えるソフトウェアとか存在しますし、その場合に気付けません。

pre-commitフックで弾く

後輩が似たようなことをやっていたので参考に、pre-commitで弾くようにしました。pre-commit~/.gitconfigに、init.templatedirを設定しておくと、その内容をリポジトリの初期化時にコピーしてくれるので、これを設定します。

[init]
  templatedir = ~/.git_template

フックスクリプトはこのような感じ。originのURLを取得して、期待と異なるユーザ情報であればエラーになります。

#!/bin/sh
# ~/.git_template/hooks/pre-commit
origin=$(git config --get remote.origin.url)

function must()
{
    local v=$(git config --get $1)
    if ! [[ $v =~ $2 ]]
    then
        echo >&2 "$1=$v: must match $2" 
        exit 1
    fi
}

case $origin in
*.example.com[:/]*)
    must user.name user1
    must user.email user1@example.com
    ;;
*)
    must user.name lufia
    must user.email lufia@example.org
    ;;
esac
exit 0

この方法では、途中で~/.git_template/hooks/pre-commitを変更しても、すでに存在するリポジトリのフックは変更されないところです。気になるなら、gitのhookを全リポジトリで共有するのように設定してみるといいかもしれません。