この記事は SmartHR Advent Calendar 2019 14日目の記事です。
はじめに
私は 3人目あるいは 4人目のエンジニアとして、 2016年2月に SmartHR に入社しました。
あれから約4年、今となっては順調に権限移譲の進んでいる SmartHR ですが、当時は正社員が 7人しかおらず、全社員が様々な仕事を行う小さな企業でした。
当然エンジニアである副社長の @kakipoはプロダクトコードを書いていますし、非エンジニアである @miyasho88も SmartHR にコードを書いては PR を投げていました。
こういった、創業者がコードに込めた思いというのはとても重要であり、おいそれと上書きしてよいものではありません。
この記事では、入社から 4年弱の期間、私がいかにして創業者のコードを上書きしないで済んだのか、その方法をお伝えします。
うっかり上書きしないために
さて、では実際にどのようにしてコードの上書きを避けるのか説明します。その答えはいたって簡単で、 Git Hook にスクリプトを仕込むことで解決します。
commit する際に修正箇所の最終編集者を確認、創業者として指定したアカウント名が変更に含まれている場合はエラーを出して commit を中止する、という流れになります。
このスクリプトを実行するためには、創業者が commit に利用したアカウント名がわかる必要がありますので、それはなんとかして手に入れてください。
なお、本記事で扱うコードはほぼデフォルトの macOS Catalina 上でのみ動作を確認しておりますので、そのほかの環境では正常に動作しない可能性がありますのでご了承ください。
処理の流れ
スクリプト内で行われる処理の流れとしては以下のようになります。
- git hook の pre-commit でスクリプトが実行されます
- git diff から変更のあった行を取得します
- git blame を使って変更のあった行を誰が書いているのか確認します
- 指定したユーザ名が含まれる行を変更している場合にはメッセージを出力して git commit を中止します
コード
プロダクト直下から .git/hook/pre-commitに以下のコードを追記します
BOSS_NAMES=YOUR_BOSS_NAME # カンマ区切りで複数指定可能ですfile_names=(`git diff --cached--name-only`)for file in${file_names[@]};do
git_diffs=(`git --no-pager diff --cached--no-ext-diff-U1000000${file} | $(cd$(dirname$0)&&pwd)/diff-lines.sh | grep-E"^[^\"].*\:[0-9]+\:\-"`)for git_diff in${git_diffs[@]};do
line=(`echo${git_diff//:/}`)origin=`git blame -L${line[1]},+1 HEAD^ ${file} | awk'{print $2}' | sed-e's/^(\(.*\)/\1/'`if[[${BOSS_NAMES}==*${origin}*]];then
echo"You will overwrite ${origin}'s code in *****:${line[1]}"is_boss_exist=true
fi
done
done
if["${is_boss_exist}"];then
echo"Commit aborted."exit 1
fiなお、ここでは簡単のために、 gitで変更ファイルの差分行番号を取得するには? - どこでも見れるメモ帳で書かれているコードをお借りして行番号を取得しています
そのため、上記のブログで使われている diff-lines.shを .git/hookディレクトリに保存し、 chmod +x .git/hookとして実行権限を付与する必要があります
実際の動作
ちゃんと abort されましたね 
どこで誰のコードを消したり上書きしようとしているか一目瞭然です。便利。
最後に
今回はうっかり創業者のコードを上書きしないために Git Hook を使ってコミットを中断させました。
しかし、動画作成のためにいろいろと探してみたのですが、 社長のコードはほぼ残っておらず、結果的として 2015年に作られた 12番目の PullRequest をチェックアウトすることとなりました。 とても残念です
いつの間にか大量に書き換えていた事実に驚愕です。
記憶があれば、来年は おまえは今まで書き換えた創業者のコードをおぼえているのか?をお送りいたします。
明日じゃなくて来年です。みなさま良いお年を!

