githooks を使って会社とプライベート用の Author を自動変更するようにしたった

Written by @ryysud

Jan 30, 2018 21:54 · 1497 words · 3 minutes read #git

まえおき

自分の場合、業務での開発は会社用の Author を利用していて、業務時間で OSS に対してパッチを投げる必要が出てきた際にはプライベートの Author に切り替えて commit を行っております。

具体的には OSS への commit 前に毎回毎回以下のコマンドを実行している感じ・・・

$ git config --local user.name "Yamada Taro"
$ git config --local user.email "yamada-taro@private.com"

しかし、さすがに面倒臭くなってきたので githooks を使って会社とプライベート用の Author を自動変更するようにしたので、同じことで困っている人のために(果たして存在するのか・・・)も手順を書きなぐっておこうと思います。

githooks ってなーに🤔

Git において特定のアクションが行われたときにスクリプトをキックする機能で、様々な hook が提供されています。今回は git commit の前に Author を自動変更するスクリプトをキックさせたいので pre-commit という githooks を使っていきたいと思います。

pre-commit

This hook is invoked by git commit, and can be bypassed with the –no-verify option. It takes no parameters, and is invoked before obtaining the proposed commit log message and making a commit. Exiting with a non-zero status from this script causes the git commit command to abort before creating a commit.

https://git-scm.com/docs/githooks#_pre_commit

これをこうしてこうじゃ👨🏻‍⚕️

流れを説明していきます。

以下のような基本的な ~/.gitconfig があったとします(どちらも意味合い的には同じコマンド)

### git コマンド経由
$ git config --global -l
user.name=Yamada Taro
user.email=yamada-taro@private.com

### ファイルを直接参照
$ cat ~/.gitconfig
[user]
    name = Yamada Taro
    email = yamada-taro@private.com

まずホームディレクトリに .git_template/hooks ディレクトリを作成する

$ mkdir -p ~/.git_template/hooks

次に pre-commit というファイルにキックさせるスクリプトを仕込んでいきます。 ファイル名は pre-commit でないとキックされない(正確には git commit 後にキックされない)ので要注意!!!

$ vi ~/.git_template/hooks/pre-commit

キックさせるスクリプトですが処理の流れは以下のとおりです。

① remote origin の URL を取得
② 既に変更されていないかチェック(自動変更は初回のみ)
③ 会社のドメインかチェック(SSH でも HTTP でも対応可)
④ 会社用の Author に変更する

中身はこんな感じ。手元で使うときに定数を自身の情報に変更してください。

#!/usr/bin/env bash

readonly REMOTE_ORIGIN_URL=$(git config --local remote.origin.url)

readonly COMPANY_GIT_DOMAIN="black-kigyo.com"
readonly COMPANY_GIT_USER_NAME="Shachiku Taro"
readonly COMPANY_GIT_USER_EMAIL="shachiku-taro@black-kigyo.com"

readonly LOCAL_GIT_USER_NAME=$(git config --local user.name)
readonly LOCAL_GIT_USER_EMAIL=$(git config --local user.email)

# Skip if the Author has been changed
if [[ ${COMPANY_GIT_USER_NAME} = ${LOCAL_GIT_USER_NAME} ]] \
    && [[ ${COMPANY_GIT_USER_EMAIL} = ${LOCAL_GIT_USER_EMAIL} ]] ; then
    exit 0
fi

# Change the Author to company information
if [[ ${REMOTE_ORIGIN_URL} = *${COMPANY_GIT_DOMAIN}* ]] ; then
    git config --local user.name "${COMPANY_GIT_USER_NAME}"
    git config --local user.email "${COMPANY_GIT_USER_EMAIL}"
    git reset HEAD . # Because you can't change the Author of staged files
    echo "[WARN] Configure the Author (name, email) and unstage files."
    echo "[WARN] Please run git-commands again."
    exit 1
fi

次に ~/.git_template/hooks/pre-commit に実行権限を付与します
実行権限を付与しないとキックされないので要注意!!!(付与してなかったら怒ってくれる)

$ chmod +x ~/.git_template/hooks/pre-commit

最後に以下の設定を ~/gitconfig に適用させます

### 直接 ~/gitconfig を編集しても良いです
$ git config --global init.templatedir '~/.git_template'

### init.templatedir が設定されたことがわかる
$ git config --global -l
user.name=Yamada Taro
user.email=yamada-taro@private.com
init.templatedir=~/.git_template

$ cat ~/.gitconfig
[user]
	name = Yamada Taro
	email = yamada-taro@private.com
[init]
	templatedir = ~/.git_template

実際に Author を自動更新するか確認する

会社用のリポジトリをクローンする

$ git clone https://black-kigyo.com/shachiku-taro/automatically-change-author.git

local な Author が設定されていないことを確認 = global な Author が使われる

$ cd automatically-change-author
$ git config --local -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
remote.origin.url=https://black-kigyo.com/shachiku-taro/automatically-change-author.git <--- 会社のドメイン入ってる
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

このままだと global なやつが使われてしまう・・・!

$ git config --global user.name
Yamada Taro

$ git config --global user.email
yamada-taro@private.com

commit するとスクリプトがキックされて自動更新後の WARN が出力される

$ touch empty-file
$ git add empty-file
$ git commit -m"Add empty-file"
[WARN] Configure the Author (name, email) and unstage files.
[WARN] Please run git-commands again.

local の Author が会社の情報に自動更新されていることがわかる

$ git config --local -l
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
remote.origin.url=https://black-kigyo.com/shachiku-taro/automatically-change-author.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
user.name=Shachiku Taro <--- change!
user.email=shachiku-taro@black-kigyo.com <--- change!

再度 commmit すると・・・

$ git add empty-file
$ git commit -m"Add empty-file"
[master 5f2d3ce] Add empty-file
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 empty-file

会社の情報で commit で・・できてる・・・!

$ git log
commit 5f2d3ce5f7d15afdd60e8774f8ac0386964fc953
Author: Shachiku Taro <shachiku-taro@black-kigyo.com>
Date:   Tue Jan 30 23:13:49 2018 +0900

    Add empty-file

やったあああああああ ✌(‘ω’✌ )三✌(‘ω’)✌三( ✌’ω’)✌

まとめ

githooks を活用すれば開発効率が向上すること間違いなしですし、アイデア次第でどんなことも実現可能なので非常にオススメです👏

自分個人としても pre-commit 以外使えていないので、更に活用していきたいと思います😄

余談

今回の記事を書いてるときに気付いたのですが https://git-scm.com のタイトルがアクセスの度にオプションが更新されててすげえイケてた

git-scm.png