GITでリモートブランチへpushする前にやっておくべきこと

先日GITを使ってて、ちょっとお粗末なミスをしてしまいました。
今日はそんなミスを犯さないためにやっておくべきことについて書きたいと思います。

お粗末なミス

私がやっちゃったミスは、ずばり「コミットグラフ汚し」です。
図のように、「別の人」とのマージコミットをコミットグラフに追加してしまいました。

このときのコミットグラフ

マージコミットのメッセージは

「Merge branch 'xxxx' of ....」
「Merge commit 'xxxx'」

という本質的でないメッセージになります。
この「マージした」という情報は「自分 <==> ある時点でのコミット」のマージを指しており、チーム全体(リモート)として意識するようなコミットログではありません。
このようなコミットをしてしまったことによって、リモートブランチのコミットグラフの見通しを悪くしてしまいました。

本来はこのようなコミットログは含まず、各人の変更した内容が集約されてコミットグラフが形成されるべきだと思います。

リモートブランチのあるべきコミットグラフの姿

今回はこのようなコミットグラフのあるべき姿を保つための方法をまとめてみたいと思います。


【2013/06/30】
コメントを受けて「リモートブランチのあるべきコミットグラフの姿」の画像を差し替えました。
(元の図はコチラ)
 

まずはgitxの導入

まずはgitxを導入することがスタートラインになると思います。
導入はとても簡単でダウンロードして解凍するだけです。
導入後、メニューから「GitX」→「Enable Terminal Usage...」を選択するとコマンドラインから「gitx」を実行出来るようになります。

GitX - Home

gitxはコミットログやコミットグラフをGUIで見れるツールです。
ローカル/リモートの複数ブランチの状態を合わせてみたり出来るため、視覚的に分かりやすいツールだと思います。(Win系だと似たようなものでgitkというツールがあります。)

コミット/マージ/リベース等を実行するたびにgitxで想定通りのコミットログやコミットグラフとなっているか?を確認しながら進めていくのが良いと思います。

それでは本題

それでは本題のどうすればリモートのコミットグラフを汚さずに済むのか?について。
全体のイメージはこのようになります。
ローカルのmasterブランチでリモートブランチと同期を取りながら、自分の作業はworkブランチにコミットしていくようにします。

以降ではこの図を元に、ひとつひとつ手順を展開していきたいと思います。

(1)作業用ブランチ(work)を作成する

まずは作業用ブランチ(work)を作成します。
「git checkout -b」を利用すると作成&そのブランチへの移動を同時に実施できます。
git checkout -b work

(2)もろもろ開発〜コミット

通常通り開発し、作業用ブランチ(work)へコミットします。
git commit

(3)リモートブランチと同期

もろもろ開発していくと「そろそろリモートへpushしたいな」と思います。
そう思ったらまずはmasterブランチとリモートブランチの同期を取ります。
この時点で「別の人」がpushしていた内容を取得します。
git checkout master
git pull origin master

(4)masterブランチをベースに作業用ブランチ(work)をリベース

ここが1番のポイントです。
リモートブランチの最新と同期を取ったmasterブランチをベースに作業用ブランチ(work)をリベースします。
ここでリベースすることによってマージコミットを発生させないようにします。
git checkout work
git rebase master

(5)作業用ブランチをベースにmasterブランチをリベース

今度は逆に作業用ブランチ(work)をベースにmasterブランチをリベースします。
ここでの目的は「master = work」という単なる位置合わせなので、「git merge --ff-only」を利用してもOKです。
git checkout master
git rebase work
(もしくは git merge --ff-only work)

(6)リモートブランチへpush

ここまで作業したらgitxでコミットグラフを確認します。
きっと綺麗なコミットグラフになっていると思うので、その確認が済んだらリモートブランチへpushします。
git push origin master

※もしgitxで確認した結果が思い通りになっていなければ元に戻しましょう。

git reset --soft xxxxxxx

これで編集したファイルはそのままに、コミットログだけを取り消すことが出来ます。

まとめ

今回はコミットグラフを汚してしまわないための1つの方法を示しました。
ローカルブランチの「master <==> work」で整合性を保った上で、それをそのままリモートへpushするというのが、もろもろ保証できて良いと思っています。

また「リモートブランチへpushする前に」というテーマでしたが、これは「pull requestを送る前に」とも読み代えることが出来ます。
OSSプロジェクトやその他何に対してもですが、コミットグラフを意識したエレガントなpull requestを送りたいものですね。