Gitを理解する

翻訳者から:この記事ではgitコマンドについては説明していませんが、読者が既にgitコマンドに精通していることを意味します。 私の意見では、公共の歴史をきれいに保つための完全に健全なアプローチを説明しています。



gitがそれを行うように促した理由がわからない場合は、苦しみが待っています。 多くのフラグ(--flag)を使用すると、gitが望むように動作するのではなく、gitが動作するはずの方法で動作させることができます。 ドライバーで釘を打つようなものです。 作業は完了しましたが、さらに悪く、遅くなり、ドライバーが台無しになります。





gitを使用した通常の開発アプローチがどのようにばらばらになるかを見てみましょう。



ブランチをマスターから作成し、作業を行い、完了したらマージバックします。



ほとんどの場合、これは期待どおりに機能します。なぜなら、ブランチを作成した後にマスターが変更されるためです(同僚がmaster-およそTranslatorでコミットすることを意味します) 。 機能ブランチをマスターにマージしても、マスターは変更されていません。 gitはマージコミットの代わりに、マスターポインターを最後のコミットに移動するだけで、早送りが発生します。



早送りメカニズムを説明するために、よく知られている記事から写真を借りました。 ご注意 翻訳者。











残念なことに、機能ブランチには中間コミットが含まれていました。頻繁にコミットされ、動作はバックアップされますが、動作不能なコードをキャプチャします。 現在、これらのコミットはmasterの安定したコミットと区別できません。 このような災害に簡単にロールバックできます。



そのため、「ルールブランチをマージするときに--no-ffを使用する」という新しいルールを追加しています。 これで問題は解決し、先に進みます。



それからある日、本番環境で重大なバグを見つけて、それが現れた瞬間を追跡する必要があります。 bisectを実行しますが、常に中間コミットに陥ります。 あきらめて、手を探します。



バグをファイルにローカライズします。 非難を実行して、過去48時間の変更を確認します。 これは不可能であることは知っていますが、数週間ファイルが変更されていないと非難します。 原因は、ブランチのマージ時間ではなく、元のコミットの時間であることがわかります(マージコミットは空なので、論理的です-翻訳者のコメント) 。 最初の暫定的なコミットは数週間前にこのファイルを変更しましたが、変更は今日だけで導入されました。



no-ff松葉杖、壊れた二等分、および非難の不明瞭は、ドライバーで釘を打つ症状です。



バージョン管理の再考



バージョン管理は2つの目的で必要です。



1つは、コードの記述を支援することです。 編集内容をチームと同期し、定期的に作業内容をバックアップする必要があります。



2番目の理由は構成管理です。 同時開発管理が含まれます。 たとえば、次のリリースバージョンで作業し、既存の製品バージョンの並行バグ修正を行います。 構成管理とは、何かが変更されたときを見つける機能を意味します。 エラーを診断するための貴重なツール。



伝統的に、これら2つの理由は対立します。



一部の機能を開発する場合、定期的な中間コミットが必要になります。 ただし、これらのコミットは通常ビルドを中断します。



完全な世界では、バージョン履歴のすべての変更は簡潔で安定しています。 干渉する中間コミットはありません。 10,000行あたりの巨大なコミットはありません。 きちんとしたストーリーでは、 チェリーピックを使用して編集をロールバックしたり、ブランチ間でトスしたりできます。 きちんとしたストーリーは、学習と分析が簡単です。 ただし、履歴の純度を維持することは、すべての編集を完全な状態にすることを意味します。



それでは、どのアプローチを選択しますか? 頻繁なコミットまたはきちんとした話ですか?



プレリリースのスタートアップで一緒に作業している場合、きちんとした話はあまり賄briになりません。 いつでもマスターリリースとリリースリリースのすべてをコミットできます。



変更の重要性が増すとすぐに、それが開発チームの成長であろうとユーザーベースの規模であろうと、順序を維持するためのツールが必要になります。 これには、自動テスト、コードレビュー、およびきちんとした履歴が含まれます。



機能ブランチは、良い妥協のように見えます。 並列開発の単純な問題を解決します。 あなたはコードを書くときに最も重要でない時点で統合することを考えていますが、それはしばらくの間あなたを助けるでしょう。



プロジェクトが十分に大きくなると、単純なブランチ/コミット/マージのアプローチが崩れます。 粘着テープを貼る時間は終わりました。 きちんとした変更履歴が必要です。



Gitは両方の長所を提供するため、革新的です。 開発プロセス中に頻繁にコミットし、最後に履歴をクリアできます。 これがあなたのアプローチである場合、gitのデフォルトはより意味のあるように見えます(ブランチをマージするときにデフォルトで早送りを意味する-約Translator)



アクションのシーケンス



ブランチは、パブリックブランチとプライベートの2つのカテゴリのコンテキストで考えてください。



公共のブランチは、プロジェクトの公式の歴史です。 パブリックブランチへのコミットは簡潔でアトミックで、適切な説明が必要です。 線形でなければなりません。 変更しないでください。 パブリックブランチはマスターおよびリリースです。



自分用のプライベートブランチ。 これは、問題を解決するときのドラフトです。



プライベートブランチをローカルに保存するのが最も安全です。 たとえば、デスクトップコンピューターとホームコンピューターを同期するためにプッシュを行う必要がある場合は、ブランチが信頼する価値がないことを同僚に伝えます。



プライベートブランチをパブリックシンプルマージに挿入しないでください。 最初に、reset、rebase、merge --squash、commit --amendなどのツールを使用してブランチをクリーンアップします。



自分が作家であると想像し、本の章としてコミットします。 作家は下書きを公開しません。 マイケル・クリクトンは、「素晴らしい本は書かれていない-書かれている。」



他のVCSから来た場合、履歴の変更はタブーに思えます。 コミットはすべて石で刻まれていると想定します。 このロジックに従って、テキストエディターから「元に戻す」を削除する必要があります。



プラグマティストは、編集が煩わしいものになるまで編集のみを気にします。 構成管理では、グローバルな変更のみが重要です。 中間コミットは、キャンセルする機能を備えた軽量のバッファーです。



履歴を不健全なものと見なす場合、早送りマージは安全であるだけでなく、望ましいものでもあります。 履歴の線形性をサポートし、追跡が容易です。



--no-ffの残りの引数はドキュメントのみです。 マージコミットを使用して、最新の製品コードに関連付けることができます。 これはアンチパターンです。 タグを使用します。



推奨事項と例



変更の大きさ、変更にかかった時間、ブランチがどれだけ遠くに行ったかに応じて、3つの単純なアプローチを使用します。



クイック編集


ほとんどの場合、クリーニングはスカッシュコミットです。

機能ブランチを作成し、1時間以内にいくつかの中間コミットを行ったとします。



git checkout -b private_feature_branch touch file1.txt git add file1.txt git commit -am "WIP"
      
      





完了したらすぐに、単純なマージの代わりに、次のことを行います。



 git checkout master git merge --squash private_feature_branch git commit -v
      
      





次に、コミットに関するより詳細なコメントを書くのに少し時間を費やします。



さらに編集


時々、機能の実装は、多くの小さなコミットを伴う複数日のプロジェクトに成長します。



編集を小さな部分に分割することにしました。そのため、スカッシュは粗すぎるツールです。 (毎日の規則として、「コードレビューを行うのは簡単ですか?」)



私の中間コミットが論理的な進歩だった場合、 rebaseをインタラクティブに使用できます。



インタラクティブモードは強力です。 これを使用して、古いコミットを編集したり、それらを分割または整理したり、この場合は複数のコミットを結合したりできます。



機能ブランチ:



 git rebase --interactive master
      
      





コミットのリストを含むエディターが開きます。 各行は、実行するコマンド、SHA1ハッシュ、およびコミットのコメントです。 以下は可能なコマンドのリストです。



デフォルトでは、各コミットには「ピック」があり、これは「コミットを変更しない」ことを意味します。



 pick ccd6e62 Work on back button pick 1c83feb Bug fixes pick f9d0c33 Start work on toolbar
      
      





コマンドをsquashに変更し、現在のコミットを前のコミットと結合します。



 pick ccd6e62 Work on back button squash 1c83feb Bug fixes pick f9d0c33 Start work on toolbar
      
      





私は保存し、別のエディターがマージされたコミットに関するコメントを要求するようになりました。 すべて準備完了です。



失敗したブランチ


おそらく機能ブランチは長期間続き、他のブランチはそれに関連性を維持するためにマージされました。 話は複雑で混乱しています。 最も簡単な解決策は、大まかな差分を取り、新しいブランチを作成することです。



 git checkout master git checkout -b cleaned_up_branch git merge --squash private_feature_branch git reset
      
      





これで、作業ディレクトリは私の編集でいっぱいになり、前のブランチのレガシーはなくなりました。 次に、編集を追加してコミットします。



要約する



gitのデフォルトに苦労している場合は、その理由を自問してください。



不変で、アトミックで、容易に追跡可能な公開ストーリーを考えてください。

プライベートストーリーが可変かつ柔軟であることを考慮してください。



手順は次のとおりです。




All Articles