正確に書くと、originのドメイン毎にuser.email
とuser.name
を切り替える、です。
僕の職場では、コードを社内に構築したGitHub Enterprise環境にpushしてて、こっちは社用のメールアドレスで登録しています。
一方で、個人的な開発をすることがある場合はGitHubを使うのですが、こっちは個人用のGmailアドレスです。
で、git configに個人用emailをグローバル設定してたりすると、うっかりGitHub Enterpriseのリポジトリにそっちでcommitしちゃったりしてしまうことがあるんですよね。
リポジトリ毎に git config --local user.email hoge@fuga.com
とちゃんと設定すればいいんですが、大抵忘れてて後でrebase祭りになる……
という具合でいろいろ面倒だったので、pre-commit
で勝手に書き換えてくれるようにしてみました
こうなった
githubから適当にリポジトリをpullしてきてcommitする
$ git config --get user.email # 元は会社アカウント(ここでの表示はダミーデータ)
ry023-yyyyyy@ry023-company.com
$ git config --get user.name
global_dummy
$ git commit --allow-empty -m dummy-commit # commitしようとするとrejectされ、設定が上書きされる
changed user.name to ry023
changed user.email to ry023-xxxxxxx@gmail.com
try again!
$ git config --get user.name # 設定が変わっていることを確認
ry023
$ git config --get user.email
ry023-xxxxxxx@gmail.com
$ git commit --allow-empty -m dummy-commit # もう一度やると、正しいアカウントでcommitされる
[master cd57d5b] dummy-commit
$ git show HEAD
commit cd57d5bd3bf8eb461d4532e9133a232a92aeab0b
Author: ry023 <ry023-xxxxxxx@gmail.com>
Date: Sat Apr 14 16:29:35 2018 +0900
dummy-commit
設定やら
gitのv2.9から、core.hooksPath
というconfigからhookのpathを変更できるようになったらしいです。
以下のようにすると~/.git/hooks
が全リポジトリの共通のhook置き場になります
$ mkdir -p ~/.git/hooks
$ git config --global core.hooksPath ~/.git/hooks/
~/.git/hooks/pre-commit
というファイルを作って次のような感じのshell scriptを配置してやると終わりです!
頭の部分はよしなに変更してやってください
(実行権限が必要なので chwon +x ~/.git/hooks/pre-commit
することも忘れずに)
#!/bin/sh
#### アカウント設定。ここに書くか、bash_profileやらzsh_profileやらに書いておく ####
GITHUB_DOMAIN="github.com"
GITHUB_NAME="ry023"
GITHUB_EMAIL="ry023-xxxxxxx@gmail.com"
GHE_DOMAIN="your-company-github.com"
GHE_NAME="ry023"
GHE_EMAIL="ry023-yyyyyy@ry023-company.com"
###################################################################
raw_url="$(git remote get-url origin)"
if echo "$raw_url" | grep https; then
# for https
remote_domain=$(echo $raw_url | sed -e 's/https:\/\///' | awk -F'/' '{print $1}')
else
# for ssh
remote_domain=$(echo $raw_url | sed -e 's/^.*@\(.*\)/\1/' | awk -F'/' '{print $1}' | awk -F':' '{print $1}')
fi
case "$remote_domain" in
"$GITHUB_DOMAIN" )
NAME=$GITHUB_NAME
EMAIL=$GITHUB_EMAIL
;;
"$GHE_DOMAIN" )
NAME=$GHE_NAME
EMAIL=$GHE_EMAIL
;;
* )
echo "unknown remote domain $remote_domain"
exit 0
;;
esac
FAIL=false
if [ "$(git config --local --get user.name)" != $NAME ]; then
git config --local user.name $NAME
echo "changed user.name to $NAME"
FAIL=true
fi
if [ "$(git config --local --get user.email)" != $EMAIL ]; then
git config --local user.email $EMAIL
echo "changed user.email to $EMAIL"
FAIL=true
fi
if $FAIL;then
echo "try again!"
exit 1
fi
余談: 本当はアカウントの変更からcommit完了までpre-commit内で一括してやりたかったのですが、どうやらpre-commitでアカウント変更してもそのコミット自体は前のアカウントのままになるようです。もっといいやり方あるのかな?