Blog

制作現場の日常

gitの歴史を整理しよう

こんにちは、プログラマーの渡辺です。

制作現場ではgitを使用してソースコードのバージョン管理を行っています。
gitではコミット単位で差分を保存できますが、基本的には機能単位や修正単位でコミットを行っています。
ある程度大きな単位でコミットすることで、特定の機能が不要になった際にはコミットを削除することで対応できるようになります。
また、不具合があった場合はどのどのような実装/修正が行われたのかを把握しやすくなり、不具合の原因を見つけやすくなります。
あとからプロジェクトに参加した人などが、実装の履歴を追いやすくなるメリットもあります。

機能単位でコミットされている図

しかしながら、作業中となるとこうは行きません。
仮のデータで実装を進めることもあるでしょうし、細かいコードの整理もあります。
実装作業中にバグが発生したときや、既存の実装を変更した際には確認のために一つ前の状態に戻したくなることも多いです。
そのため、できれば作業中は作業単位でコミットをしたくなります。

作業中のコミットの様子

しかしながら、作業単位での細かいコミットは、大きい単位でのコミットと真逆の性質があります。
すなわち、機能/修正の巻き戻しに正確に複数のコミットを削除しなければならず、不具合のコミットを把握しづらく、実装履歴を追うのが難しくなります。
特に複数のコミットを削除するには、実装内容を正確に把握しておく必要があり、迂闊なことをしてしまうと別の不具合が発生するなど、とても難しく、煩雑な作業になります。

このように、作業単位でのコミットと機能単位でのコミットにはそれぞれメリット/デメリットがあります。
これらのメリットだけを享受するには、作業中には作業単位のコミットをし作業完了後には機能単位でのコミットを行う必要があります。
そしてgitにはこのようなわがままを可能にするため、rebaseという機能が備わっており、この機能を使うことで、作業単位のコミットを一つの機能単位のコミットとしてまとめるとができます。

rebaseはgitのコミットの歴史に対し、以下の様なことができます

  • コミットメッセージの変更
  • コミットの順番の変更
  • コミットの削除
  • コミットをまとめる

今回はコミットをまとめる機能を使用し、作業中のコミットを機能単位のコミットへまとめます。
今回はコミット3cd6~0326までのコミットをまとめるので、コマンドは以下のようになります
git rebase -i 5d96
指定するコミットIDはまとめたいコミットの一つしたのコミットIDを設定する必要があります。
コマンドを実行すると、歴史を編集するためにエディタが立ち上がります。

歴史編集画面

今回は0326のコミットに他のコミットをまとめます。
squashを設定することで、一つ上のコミットに自身をまとめることができるのでe216~3cd6のpickのところを、squashに変更します。
変更を保存し、エディタを閉じると今度はコミットメッセージの編集画面が立ち上がります。

コミットメッセージの変更画面

このまま保存して閉じるこで、コミットはまとまりますが、
今回は新スキルの実装としてまとめるので、既存のメッセージをすべて削除し
新しいコミットメッセージを追加します。

新しいコミットメッセージ

コミットメッセージを追加した状態で、保存してエディタを閉じることでrebaseが完了し、一つのコミットとしてまとめることができました。

作業コミットが一つのコミットにまとまった図

rebaseには他にもいろいろ便利な機能があります。
もし気になる機能があれば実際に使ってみるとより開発が捗ります。
もちろん、いつも綺麗にrebaseできるわけではありませんが、何かあったときはrebase --abortでrebase前の状態に戻すことができるので、どんどん試してみるのがおすすめです。

以上制作現場からの日常でした。
最後までお付き合いいただきありがとうございました。

次の記事へ