私は常にMercurialのマントラに同意しました 1しかし、現在Mercurialはrebase拡張機能にバンドルされており、それがgitでよく使われているので、それが本当に「悪い習慣」と見なされるのか、または少なくとも使用を避けるのに十分悪いのかと思います。いずれにせよ、リベースはプッシュ後に危険であることに気づいています。
OTOH、5つのコミットを1つのコミットにパッケージ化してそれをより見栄えよくすること(特に本番ブランチ)にしようとするポイントを理解していますが、個人的には、一部の機能の部分的なコミットを確認できる方が良いと思いますそれほど気の利いたものではない場合でも実験は行われますが、「Xの方法で試してみたが、結局Yほど最適ではなく、YをベースにしてZを行う」のようなものを見ると、調査する人にとってIMHOの価値は高くなります。コードベースを作成し、開発者の考え方に従ってください。
私の非常に独断的な見方(ダム、内臓、偏見など)は、プログラマーが間違いを隠すためにリベースを好むということです...そして、これはプロジェクトに良いとは思いません。
したがって、私の質問は、そのような「有機的なコミット」(つまり、改ざんされていない履歴)を実際に実行することは本当に価値があると思いますか?または、逆に、十分にパックされた気の利いたコミットを実行し、プログラマーの実験プロセスを無視することを好みますか?;どちらを選択した場合でも、なぜそれが有効なのですか?(他のチームメンバーが履歴を保持するか、またはリベースするか)。
1Google DVCS分析 、Mercurialの「History is Sacred」。
履歴は神聖ですが、プレゼントは神聖ではありません。 DVCSの「ツリー」を2つの部分に分割できます。
past/ historyには、コードの現在の状態に到達した方法の正確なビューが含まれています。歴史のこの部分は時間とともに成長します
presentコードを進化させるために現在取り組んでいる部分。このヒントの歴史の大部分は、常に同じサイズです。
あなたがリリースした、または何らかの方法で使用したすべてのコードは、pastの一部です。セットアップを再現したり、回帰の原因を理解したりする必要があるため、過去は神聖なものです。 過去を書き換えることは決してありません。 gitでは通常、マスターになったら何も書き換えることはありません。マスターは履歴のpast部分です。 Mercurialには パブリックフェーズコンセプト があり、「ツリー」のpast部分を追跡し、その不変性を強制します。
コードのpresent部分は、現在作業しているチェンジセットです。使用可能、バグフリー、適切にリファクタリングしようとしている機能ブランチ。 書き直しても問題ありません過去より美しく、シンプルで使いやすい部分。 Mercurialはdraftフェーズでこれを追跡します。
ですから、履歴が改善されたらリベースしてください。 Mercurialは、リベースしてはいけないものをリベースする場合、足元で自分を撃つことを防ぎます。
多くの小さな依存している変更とは対照的に、1つの大きな一貫した変更がある場合、コードレビューははるかに簡単です。
私は新しい機能に取り組んでいるとき、私のブランチにたくさんの小さな変更をコミットしたいです。パッチを提出する準備ができたら、それらの小さなコミットを、その機能に必要なすべての新しいコードを表す1つの大きなコミットにまとめます。ここでリベースが役に立ちます。
一方、コミットが互いに何の関係もない場合、リベースはお勧めできません。複数の機能の追加は、個別のコミットである必要があります(理想的には、個別のブランチから行われます)。
すべてのミスが非表示にする必要があるようなものではありません。たとえば、私が誤ってバイナリファイルをリポジトリにコミットしたことがあります。履歴を改ざんすることは、障害が履歴自体に限定されていない場合、つまり、コミットされるべきではないファイルがコミットされている場合にのみ悪いことです。
あなたの質問は、履歴を一連の順序付けられたコード変更として説明し、有機的なコミットが将来の読者を開発プロセスの手掛かりにするかどうかを尋ねます。しかし、リリース/インテグレーションエンジニアとして、私は履歴をコードとして考えることはあまりありません。私の歴史が語る物語、それが保持する制度的知識、そしてそれが問題を迅速にデバッグすることを可能にするかどうかに、私はもっと夢中になっています。
私のワークフローでさえ、有機的なワークフローがこれをうまくやるとは思いません。コーディング時にDVCSについて評価する品質(安価なブランチ、クイックコミット、リモートへの保存を頻繁に行うなど)は、会社の 統合マネージャーとして重視するものではありません。 その役割では、git rebase
またはgit merge
よりもはるかに頻繁にgit diff
、git apply
、git add
、およびgit commit
を発行します。 rebase
のようなツールを使用すると、与えられたコードを、機能するものから保守可能なものに変換できます。
非論理的またはあいまいなコミットは有用ではありませんが、コードを機能させることを他の人に配布しないことが主な関心事である場合、それらを有機的に簡単に書くことができます。 Case 15: Fixed a problem
やRefactored <cranky legacy feature>
のようなコミットは、私がそれらを作成した場合でも、メンテナンスの自己を不快にさせます。ただし、「増分」コミットのようなブラックアウトの怒りを誘発するものはありません。先日、開発者が私に渡したこのトピックブランチについて考えてみます。
$ git log production..topic --oneline
f9a1184 incremental update
156d299 incremental commits
e8d50b0 new incremental updates
511c18c incremental updates, refactor
1b46217 incremental upgrade
9e2b3b8 incremental update
fa68a87 incremental update
これらは悪です。ファウスト博士のために設計されたDVCSのようなものです。迅速かつ簡単なソース管理を提供します。あなたは私にあなたのコードメンテナーの魂を与えます。すべての遅延コミットは利己的な行為です。私たちの多くはそれらを書いていますが、私たちの将来は論理的で複製可能なデバッグ可能な履歴も負っています。 rebase
への何らかの方法がなければ、それを行うことはできません。
失敗した実験については、私たちの(新しく)コミットメッセージでそれらを説明してみませんか?今から1年後は、半完成のスニペットは必要ありません。中止された試みの記録と、もし私がもう一度それを試すほど愚かであると思うなら簡単な説明が欲しいだけです。成功するワークフローは世界中にたくさんありますが、壊れたコードを本番用のコードベースに故意にコミットしようとする理由を考えるのに苦労しています。
神聖なものは何もありませんが、自分がしていることに正当な理由があることを確認してください。リベースは、適切に使用すると非常に強力ですが、強力なツールと同様に、不注意に使用すると混乱を招き、問題を引き起こす可能性があります。
個人的には、最終的なテストを実行して機能をメインブランチにマージする前に、トランク(またはメインの開発ブランチ)に対してローカルの機能ブランチをリベースすることは非常に便利です。そうすれば、実際にマージする前に、マージの競合などに対処できます。
私見、実験は通常、ベースラインではなく、棚または一時的なブランチに属します。これに従えば、すべてのコミットが論理的に健全であり、何らかの価値を追加するため、問題はありません。