読者です 読者をやめる 読者になる 読者になる

「git commit するまえに考えるべき10のこと」がDVCS的じゃない件

DVCS

はじめに

git commit するまえに考えるべき10のこと | Act as Professionalを読んでいろいろと思うことがあったので書きました。
これはSCMBootCamp主催者としてとか、Mercurialユーザーを代表してとかではありません。
僕はこう思う。ということです。
読むの面倒な人は最下部のまとめだけ読めばok。

commit != push

DVCSの利点はローカルコミットという概念を持ち込んだことです。これにより、高速な履歴追加、安全なマージを手に入れることができました。


件の記事を読んでいて気になったのは、commitという単語です。
特に、

  • 1コミットに1つの対応
  • コメントアウトしたコードをコミットしない
  • テストが正常に通過したものにしてください
  • コミットメッセージの1行目は”短い説明”
  • コミットメッセージのスタイル
  • コミットメッセージのボディは有意義な内容にする
  • 他人が理解できるメッセージ


が関わってきます。


結論から言うと、これらは全て「publicにする前に考えるべきこと」です。
gitで言えば、merge, push などをする前になります。


Mercurialではphaseという概念があり、対象リビジョンがprivateかpublicであるかが管理されています。これによってpublicなリビジョンに対する歴史改変などはオプションなしでは不可能にされています。(他の人が取り込んでいる可能性があるものは気軽に歴史改変できないようになっている。


履歴からの復帰

VCSとしての利点である「いつでもロールバックできる(過去の履歴から管理対象を戻せる)」を考えた時に「1つの対応」という区切りで戻りたいのでしょうか?


件のブログにある1つの対応というのはいわゆるトピックブランチ的な粒度に見えます。トピックブランチとフィーチャーブランチの違いは開発スタイルによるので、同一になる場合もあれば、異なる場合もあると思います。
ここでは、トピックブランチ的な粒度というのは、5,6人で開発しているときに、1人が1日以内で行える作業量程度とします。


仮に1日以内に3つの対応をしたとします。この場合は3コミットすることになります。
3コミットした場合に「1.4コミット目くらいの時間帯の状態に戻る必要がない」といえるのでしょうか?
少なくとも僕は言えません。間違いなくIDEのローカルヒストリーを使います。
つまり、VCS以外で履歴を管理しているという状況が発生します。それ自体は悪くないことですが、それを考慮しての意図なのかはわかりませんでした。

分散という自由

ローカルコミットは自分で自由にかけられる保険です。
先の制約は個人的には、TDDするなと言われているくらいには厳しいものがあります。
僕はローカルコミットにおいては「git commit するまえに考えるべき10のこと」のようなことは考えなくていいと思っています。


たしかにlogが煩雑になるかもしれませんが、rebase -i であとからまとめることもできますし、mergeスタイルであれば、mergeされたコミットのみをlogコマンドのオプションで表示することもできます。
materブランチのみを表示することもできます。
(個人的には、logコマンドを素で打って汚いって言っているのは、あまりにツールに不慣れすぎであると言わざるを得ないというか、メリット、デメリット考えずにツールが持つ可能性を絞っていると言わざるを得ません。


対応をまぜないこと

時系列的に複数の対応がまざるのはたしかに面倒になります。
細かいコミットと歴史改変をつかいまくることで対応単位に区切り直すことはできますが、あまりに非効率でしょう。
複数の対応を一気にとらないというのは重要なことなので同意です。
僕と意見が違うのは、コミットと対応の関係です。

テストについて

一番目についたのは
付属のテストスイートがすべて正常にパスすること
です。
これってローカルでは全てのテストを実行すべきということでしょうか。
ある程度の規模を超えるとテストの実行時間は長くなります。
それをさけるためにCIでやったり、更に分散ビルドをしているはずです。


また、「このテストが通らないので直してください」とテストコードのみをコミットすることもあります。というか、僕は職業柄基本的にその流れが多いです。

まとめ

「git commit するまえに考えるべき10のこと」のいくつか(とくに1コミット1対応)はSVN時代のcommit == push の考えだと思う。
「git push するまえに考えるべき10のこと」ならまだ納得できる。
複数の対応を同時進行させてはいけないというのは同意です。
メントスタイルとかは、現状の慣習をうまくまとめていると思います。ただ、「有意義な内容」というのはあまりにもアレな気がします。
コメント系はpublicになる前に気をつけるべきことであって、ローカルコミットそれぞれでは正直気にしなくてよい。リビジョンをrebase -iで整理しない場合には最後のコミットか、mergeコミットでは気をつけるべき。つまり、publicにするとき。
少なくともローカルで実施すべきテストコードがどのようなテストかを明確にすべき。


補足

ソースコードであれば、僕は「ファイル変更検知 -> 自動ビルド -> ビルド結果をコミットコメントにして自動コミット ->先頭に戻る」をしています。
それくらいカジュアルにコミットして、後からまとめるほうがいいんじゃないかな。
自動コミットが万能だとは思っていませんけど。