LoginSignup
13
15

More than 3 years have passed since last update.

退屈なgit commitの定型文はGitフックにやらせよう

Last updated at Posted at 2018-12-30

現在働いている会社では、チケットを立ててタスク管理をしています。
そのためgitの運用、というかブランチの命名規則として下記のように「タスク種別/チケット名」というのがあります。
例:fix/PRJ-123

そして、後で問題が見つかった時などにどのチケットに伴う作業だったのかが分かるように、コミットメッセージの先頭にチケット名を明記するようになっています。
例:refs PRJ-123, コミットメッセージ

でも、これって正直いちいち書くのが面倒です。笑
毎回git statusとかgit branchとかしてブランチ名をコピペしたりして……

こういうのは自動化させちゃいましょう!!

Gitフックを利用する

gitには、特定のアクションが発生した時にカスタムスクリプトを叩く方法があります。 
それがGitフックです。
詳しくはこちらのドキュメントをご覧ください。

自作のスクリプトを読み込む設定をする

まずは、自作のスクリプトを読み込むために、.git_template/hooks/ディレクトリを用意しましょう。

$ mkdir -p  ~/.git_template/hooks

次に、gitの方でこのディレクトリを読み込めるように設定させます。

$ git config --global init.templatedir '~/.git_template'

スクリプトの作成

ここまでおこなったら、スクリプトを作成していきます。
今回は、コミットメッセージエディターが起動する直前、デフォルトメッセージが生成された直後に実行されるprepare-commit-msgフックを作成していきます。

$ touch ~/.git_template/hooks/prepare-commit-msg

これ以外にも色々と種類があるので、確認してみると面白いと思います。

$ cd /path/to/your/project/.git/hooks
$ ls
applypatch-msg.sample  post-update.sample     pre-commit.sample  pre-rebase.sample   update.sample
commit-msg.sample      pre-applypatch.sample  pre-push.sample    pre-receive.sample  prepare-commit-msg.sample

スクリプトの中身は、以下のような感じにしました。
Macを使用する人は、下記スクリプトではsedコマンドが意図しない挙動を見せるので、こちらのQiitaの記事を合わせてご覧ください。

#! /bin/bash

#Macを使う人は、gnu-sedをインストールしてからエイリアスを設定して、
#下記2行のコメントアウトを外してください!
#shopt -s expand_aliases
#source ~/.bashrc

branchName=$(git rev-parse --abbrev-ref HEAD)  # 現在のブランチ名を返す
ticketName=$(echo $branchName | cut -d "/" -f 2)  # コミットメッセージに必要なチケット名の抽出
firstLine=$(head -n1 $1)  # git commit --amendとの区別のために最初の一行を取得

if [ -z "$firstLine" ] ;then  # 一行目が空行であれば(--amendでなければ)以下を実行
    sed -i "1s/^/refs ${ticketName},/" $1  # 最初の一行の先頭を「refs チケット名,」に書き換える
fi

補足として、head -n1 $1は何のファイルを引数にしているのかパッと見分かりにくいのですが、git commitのデフォルトメッセージです。

prepare-commit-msgフックは、コミットメッセージエディターが起動する直前、デフォルトメッセージが生成された直後に実行されます。 このフックでは、デフォルトメッセージを、コミットの作者の目に触れる前に編集できます。
--公式ドキュメントより

もしもサンプルスクリプトが生成されない場合

先に自作スクリプトを生成してしまうと、サンプルスクリプトが生成されません。
こういう時は一旦、init.templatedirをunsetして下記のように進めてみてください。

$ git config --global --unset init.templatedir
# vimを開いて[init]を念のため消す
$ vim ~/.gitconfig
$ git init
$ git config --global init.templatedir '~/.git_template'

スクリプトに実行権限を付与

スクリプトの作成が終わったら、実行権限を付与してください。

$ sudo chmod a+x ~/.git_template/hooks/prepare-commit-msg

リポジトリにてスクリプトの生成

最後に、作業が必要なリポジトリへ移動してスクリプトを生成してください。
git initをするだけです。

$ cd /path/to/your/project/
$ git init
$ cd .git/hooks/
$ ls | grep prepare-commit-msg
prepare-commit-msg  # 自作のフックスクリプトが生成されている事の確認
prepare-commit-msg.sample

コミットメッセージが自動生成されているか確認!

ここまで進めたら、実際にコミットメッセージが自動で生成されているのか確認してみましょう!

$ cd /path/to/your/project/
$ git branch
  develop
* fix/PRJ-123
$ vim test.txt  # テストファイルの作成
$ git status
On branch fix/PRJ-123
Your branch is up-to-date with 'origin/fix/PRJ-123'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    test.txt

nothing added to commit but untracked files present (use "git add" to track)
$ git add test.txt
$ git commit  # vimのエディタへ

refs PRJ-123,
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch fix/PRJ-123
# Your branch is up-to-date with 'origin/fix/PRJ-123'.
#
# Changes to be committed:
#»------new file:   test.txt
#

無事に自動生成を確認出来ました!
やったね!

もし間違えてgit commitを打っちゃったら…

ちなみに、もしも間違えてgit commitをしてしまったら、最初の一行目(ここで言うと「refs PRJ-123,」のこと)をまるっと削除してから:wqで保存してエディタを終了させればgit commitを打つ前に戻ります。

追記

2019/01/07 エイリアスも対応

上記はgit commitに対してでしたが、git pushの際も現在のブランチ名をコピペしないで出来るようにエイリアスを設定しました。

~/.gitconfig
[alias]
cb="git rev-parse --abbrev-ref HEAD"  # Current Branchの意

設定後のコマンドの入力は以下のようにします。
git push origin ${cb}
これでマウスorトラックパッドを使わずにgit commitgit pushが出来るようになりました!

13
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
15