就職して以来CVS->subversion->gitと、かれこれ10年近くVCSを使ってきましたが、今だにcommitを忘れるという初歩的な問題が解決できません・・・
- ソース作成/修正
- ビルド
- テスト
- コミット
という順番で作業してると、ビルド&テストしてる間に時間が空いてしまって作業が止まるのが原因だろうと仮定してgit-hookを使ったポカヨケを作り込んでみました。
サンプルのプロジェクトとして、懐しのはろーわーるどをCで書いてみました。
#include <stdio.h> int main(int argc, char *argv[]) { printf("hello world!\n"); return 0; }
ビルド用のmakefileはこんな感じ
LM=hello LINKER=$(CC) LDFLAGS=$(CFLAGS) SRCS_C=hello.c OBJS_C=$(SRCS_C:%.c=%.o) OBJS=$(OBJS_C) all:$(LM) $(LM):$(OBJS) $(LINKER) $(LDFLAGS) $(OBJS) -o $(LM) .PHONY: clean clean: -rm -rf *.o $(LM)
そして、テストスクリプトとして次のようなpythonのスクリプトをtest.pyとして置いておきます。
#!/usr/bin/python # -*- coding: utf-8 -*- import subprocess import sys if __name__ == "__main__": output=subprocess.check_output("./hello") if output == "Hello world!\n": sys.exit(0) else: print("FAILED!!") print output sys.exit(1)
ここまで準備できたら、次はhookを用意します。
".git/hooks/commit-msg"という名前で次のようなシェルスクリプトを作ります。
#!/bin/sh #コミットメッセージが空でなければ #ビルド&テストを実施 grep -v -e'^#' -e'^$' $1 >/dev/null if [ $? -eq 0 ];then make && python test.py exit $? fi
これでgit commitしてメッセージを書き終えると自動的にmakeとtest.pyが実行されます。
今の状態だと、hello は"hello world!"と出力するのに、テストでは"Hello world!"と出力することを期待されているのでテストに失敗し、コミットできないはずです。
ではさっそく試してみましょう。
> git add hello.c Makefile test.py > git commit -m'Initial commit' cc -c -o hello.o hello.c cc hello.o -o hello FAILED!! hello world! >git log fatal: bad default revision 'HEAD'
たしかに、コミットされてません!
hello.cを修正して、正しく"Hello world!"と出力するように変えると
git commit -m'Initial commit' cc -c -o hello.o hello.c cc hello.o -o hello [master (root-commit) c524d0b] Initial commit 3 files changed, 42 insertions(+) create mode 100644 Makefile create mode 100644 hello.c create mode 100755 test.py >git log commit c524d0bd9c1ed94fa20b9eab29a222f6312237d3 Author: n_so5 <n_so5@localhost> Date: Fri Jan 29 14:10:47 2016 +0900 Initial commit
無事にコミットされました!
あとは、必ずテストを書くという強い心があれば大丈夫・・・orz