まず、嫌な例を聞いてみましょう。
問題 F00-123 が解決されたことがわかります。これはあなたがよく知っているサブシステムのバグなので、あなたの直感がバグの最も可能性の高い原因を教えてくれます。あなたの疑いを確かめるために、バグがどのように解決されたかを確認することにしました。 デバッグ情報を削除するバグフィックスを4つの連続したコミットに絞り込むまで、長い時間をかけてバージョン履歴全体を検索します。各コミットの変更点は膨大で、十数個のファイルで数百の変更がありました。「Fuckin' @#$%%^&" とあなたは罵ろうとしましたが、頭の中で最悪の悪態をつくのをやめました。"このバグフィックスは3行以上のコードであってはならない!".
[]
上記の例に聞き覚えはありませんか?多くの開発者は、バージョン管理システムを単なるファイルのバックアップの束だと考えています。このような過去のバックアップは、ある時点のファイルの内容を取り出すこと以外には役に立ちません。以下の提案は、バージョン管理システムをバックアップシステムからコミュニケーションと文書化のための貴重なツールに変えるのに役立ちます。
1.コミットごとに1つの変更
F00-321とF00-332を修正し、クラスをリファクタリングし、インターフェイスにボタンを1つか2つ追加し、プロジェクトファイル全体のタブをスペースに変更することを1回のコミットで行った場合、基本的に誰もF00-123のバグフィックスをレビューすることはできず、あなただけがそのバグフィックスの一部である変更点を知っていることになりますが、1週間後にはおそらく忘れてしまっているでしょう。あなただけがそのバグフィックスの一部である変更点を知っていますが、一週間後にはおそらく忘れているでしょう。
また、hg backout や git revert を使って変更を元に戻すこともできません。なぜなら、そうするとバグ修正以外のすべてが元に戻ってしまうからです。
この問題の解決策は「1回のコミットで1つの変更しかしない」ことで、何をもって「1つの変更」とするかについて厳密なルールはありません。しかし、もしあなたが "and "という単語を使わずに、あなたがすることすべてを一文で説明できるのであれば、あなたはそれを成し遂げたことになります。
分散バージョン管理システムの良い特徴のひとつは、作業ディレクトリに互いに関連性のない変更がたくさんある場合に、混乱を一掃するのに使えるということですが、***そもそも混乱を起こしてはいけません。コードを修正し始める前に、修正したいものに真剣に集中する前に、何をしたいのか、どのようにしたいのかを決めてください。
特定のコード部分を改善する方法を見つけなければ、そのコード部分を変更することはなさそうです。バグを見つけたり、悪いコードを見たり、もっと知りたいと思うことがあるはずです。どんなにやりたいことがあっても、脇道にそれてはいけません。これらの発見は貴重なものなので、ノートやTODOファイルに書き留め、現在のタスクが終わるまで修正しようとしないでください。
これは、より良いコミットについてだけではありません。プログラミングの問題解決に没頭しているとき、頭の中はその問題についての詳細でいっぱいで、その瞬間に他のことを考えようとジャンプすると、元の問題の詳細を忘れてしまい、元の問題に戻るのに時間がかかります。生産性を上げるためには、タスクの切り替えを減らす必要があります。
もちろん、他の問題を解決しなければ今の作業を終わらせることが難しい場合もあるでしょう。これを行う最も簡単な方法は、hg shelve や git stash を使って未完了の変更を隠しておき、問題のある2つの変更を切り離して依存する方をコミットし、それから元のタスクに戻ることです。
2.各提出物に完全な変更を含めること
ひとつの変更が複数のコミットにまたがっている場合、その変更をレビューするのは困難です。多くの場合、これは同時にあまりに多くの問題に取り組んでいることが原因です。それほど多くの問題を食べることができないのに、それらを噛み砕くのであれば、それらのいくつかを保存しようとしたときに、そのほとんどが未完成であることに気づくでしょう。同時に多くの問題に集中しすぎると、****が完全な変更をコミットするのに時間がかかることにつながります。
変更には長い時間がかかるものもあり、プロセスのどこかでミスをした場合、最初からやり直すわけにはいかないので、プロセス中にいくつかの中間バージョンを保存しておく必要があります。幸運なことに、分散バージョン管理システムでは多くの中間バージョンを保存することができますが、***中央のリポジトリにコミットするのは一度だけです。
GitのインデックスやMercurial Queuesのパッチを使い、最後の正しい中間バージョンを保存します。新しい変更をするたびにインデックスやパッチを更新し、もし間違いがあれば、それを使って作業ディレクトリを復元することができます。私はこれをバージョン管理のためのワンスロットのクイックセーブと考えたいのです。
3.何を変更したかを説明するメモを書いてください。
Fix "や "Commit "のようなコミットには、有益な情報は含まれていません。誰かがバージョン履歴を見たいと思ったときに、このようなコミットメッセージを書くと、コードの変更点をすべて調べなければならなくなります。このような短くて不明瞭なコミットメッセージを書くことは、あなたにとっては1分の節約になるかもしれませんが、他の人の時間を何時間も浪費することになります。
良いコミットメッセージは、それを見る人にコードのどの部分がどのように変更されたかを明確にします:
SomeClass: use bleh instead of xyzzy in someMethod (fixes FOO-123)
4.この変更を行った理由
コードへのすべての変更に正当な理由や根拠があると仮定して、その理由や根拠が文書化されないままであれば、コードベース全体が次のようなリスクにさらされることになります。
- 他の開発者は、元のコードがなぜそのように書かれているのか理解していません。彼らがコードを修正すると、元の作者がすでに見つけたり避けたりしている問題を引き起こしてしまうかもしれません。
- 他の開発者は、元のコードがそのように書かれたのには理由があるに違いないと考えています。彼らはコードをブラックボックスとみなし、元のコードを修正するのを避けるために、あらゆる種類の複雑な回避策を追加します。**** このコードベースが肥大化し、コードが読みづらくなるのです。
- xyzzy (bars); + // Our bars are already sorted, so bleh is much faster than xyzzy + bleh (bars);
SomeClass: Don't flush caches in someMethod The caches are flushed automatically at the end of each request.
変更によって既知の問題が解決された場合、他の開発者がバージョン履歴を見たときに、その変更がどのような状況で行われたかを正確に知ることができるように、コミットメッセージにチケット番号を含めるようにしてください。
[]





