Gitコミット履歴をクリーンに保つ方法(および理由!)

コミットは、Gitリポジトリの重要な部分の1つです。さらに、コミットメッセージはリポジトリのライフログです。プロジェクト/リポジトリが時間の経過とともに進化するにつれて(新機能の追加、バグの修正、アーキテクチャのリファクタリング)、コミットメッセージは、何がどのように変更されたかを確認できる場所です。したがって、これらのメッセージが根本的な変更を短く正確に反映することが重要です。

意味のあるGitコミット履歴が重要な理由

Gitコミットは何をしますか?Gitコミットメッセージタッチしたコードに残す指紋です。同じ変更を確認した1年後の今日コミットするコードは、明確で意味のあるコミットメッセージに感謝します。また、それも仲間の開発者の生活を楽にします。コミットがコンテキストに基づいて分離されると、特定のコミットによって発生したバグをすばやく見つけることができ、最初にバグの原因となったコミットを元に戻すのが簡単になります。

大規模なプロジェクトで作業しているときに、更新、追加、または削除される多くの可動部分を処理することがよくあります。このような場合にコミットメッセージが維持されるようにすることは、特に開発が数日にわたる場合は注意が必要です。数週間、あるいは数ヶ月。だから、簡潔さを維持する努力を簡素化するためにコミット履歴については、この記事では、開発者がGitリポジトリで作業しているときに直面する可能性のある一般的な状況のいくつかを使用します。

  • 状況1:最新のコミットを変更する必要があります
  • 状況2:特定のコミットを変更する必要がある
  • 状況3:コミットを追加、削除、または結合する必要がある
  • 状況4:コミット履歴が作成されない感覚的には、新たなスタートが必要です!

しかし、飛び込む前に、仮想のRubyアプリケーションでの典型的な開発ワークフローがどのように見えるかを簡単に見ていきましょう。

注:この記事は、Gitの基本、ブランチの仕組み、ブランチのコミットされていない変更をステージに追加する方法、および変更をコミットする方法を理解していることを前提としています。 「これらのフローがわからない場合は、ドキュメントが出発点として最適です。

人生の1日

ここでは、小さなRuby onRailsプロジェクトに取り組んでいます。ホームページにナビゲーションビューを追加する必要があり、これには複数のファイルの更新と追加が含まれます。フロー全体の段階的な内訳は次のとおりです。

  • ファイルの更新から機能の作業を開始します。 ;それをapplication_controller.rb
  • この機能では、ビューも更新する必要があります:index.html.haml
  • インデックスページで使用されるパーシャルを追加しました:_navigation.html.haml
  • 追加したパーシャルを反映するように、ページのスタイルも更新する必要があります。 styles.css.scss
  • これで、機能に必要な変更を加える準備が整いました。テストも更新する時間です。更新されるファイルは次のとおりです。
    • application_controller_spec.rb
    • navigation_spec.rb
  • テストは更新され、期待どおりに合格しました。今度は変更をコミットします!

すべてのファイルはアーキテクチャの異なる領域に属しているため、コミットします。各コミットが特定のコンテキストを表し、特定の順序で行われるようにするために、互いに分離された変更。私は通常、バックエンド->フロントエンドの順序を好みます。フロントエンドの順序では、ほとんどのバックエンド中心の変更が最初にコミットされ、次に中間層、次にGitリストのフロントエンド中心の変更がコミットされます。

変更がコミットされたので、ブランチとのマージリクエストを作成します。マージリクエストを開くと、通常、変更がリポジトリのmasterブランチにマージされる前に、ピアによってレビューされます。次に、最終的にどのような状況になる可能性があるかを学びましょう。コードレビュー中。

状況1:最新のコミットを変更する必要がある

レビュー担当者がstyles.css.scssを確認した場合を想像してみてください。変更を提案しました。このような場合、スタイルシートの変更はブランチの最後のコミットの一部であるため、変更を行うのは非常に簡単です。これを処理する方法は次のとおりです。

  • ブランチでstyles.css.scssに必要な変更を直接行います。
  • 一度変更が完了したら、これらの変更をステージに追加します。 git add styles.css.scssを実行します。
  • 変更がステージングされたら、これらの変更を最後のコミットに追加する必要があります。 git commit --amendを実行します。
    • コマンドの内訳:ここでは、git commitコマンドに変更内容を修正するように依頼しています。最新のコミットへのステージ。
  • これにより、Gitで定義されたテキストエディタで最後のコミットが開き、コミットメッセージ「ナビゲーション用のスタイルの追加」が表示されます。
  • CSS宣言のみを更新したため、コミットメッセージを変更する必要はありません。この時点で、Gitが開いたテキストエディタを保存して終了するだけで、変更がコミットに反映されます。

既存のコミットを変更したため、これらの変更が必要です。 git push --force-with-lease <remote_name> <branch_name>を使用してリモートリポジトリに強制的にプッシュされます。このコマンドは、リモートリポジトリのコミットAdd styles for navigationを、ローカルリポジトリで作成したばかりの更新されたコミットで上書きします。

ブランチを強制的にプッシュする際の注意点が1つあります。複数の人がいる同じブランチで作業している場合、他のユーザーが新しいコミットが強制的にプッシュされているリモートブランチに変更をプッシュしようとすると、強制的にプッシュすると問題が発生する可能性があります。したがって、この機能を賢く使用してください。 Git強制プッシュオプションの詳細については、こちらをご覧ください。

状況2:特定のコミットを変更する必要があります

以前の状況では、修正が必要だったため、修正はかなり簡単でした。最後のGitコミットのみですが、レビュー担当者が_navigation.html.hamlで何かを変更することを提案した場合を想像してみてください。この場合、上から2番目のコミットであるため、変更は最初の状況ほど直接的ではありません。これを処理する方法を見てみましょう。

コミットがブランチで作成され、一意のSHA1ハッシュ文字列で識別されます。これは、あるコミットを別のコミットから分離する一意のIDと考えてください。 git logを実行すると、ブランチ内のすべてのコミットとそのSHA1ハッシュを表示できます。これにより、次のような出力が表示されます。最新のコミットが一番上に表示されます。

ここで、git rebaseコマンドが機能します。 git rebaseを使用して特定のコミットを編集する場合は常に、編集するコミットの直前のポイントにHEADを戻して、最初にブランチをリベースする必要があります。この場合、Page Navigation Viewを読み取るコミットを変更する必要があります。

ここで、変更するコミットの直前にあるコミットのハッシュに注目してください。ハッシュをコピーして、次の手順を実行します。

  • ブランチをリベースして、ターゲットのコミットの前にコミットに移動します。 git rebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20
    • コマンドの内訳:ここでは、提供されたSHA1ハッシュを使用したインタラクティブモードでGitのrebaseコマンドを実行しています。リベースするコミットとして。
  • これにより、Gitのリベースコマンドがインタラクティブモードで実行され、テキストエディタが開き、リベースしたコミットの後に行われたすべてのコミットが表示されます。 。次のようになります。

各コミットにの前、および以下のコンテンツには、使用できるすべての可能なキーワードがあります。コミットを編集するため、pick 4155df1cdc7 Page Navigation Viewedit 4155df1cdc7 Page Navigation Viewに変更する必要があります。変更を保存してエディターを終了します。

これで、ブランチは、_navigation.html.hamlを含むコミットの直前の時点にリベースされます。ファイルを開き、レビューのフィードバックに従って必要な変更を実行します。変更が完了したら、git add _navigation.html.hamlを実行してステージングします。

変更をステージングしたので、ブランチHEADをに戻します。最初に行ったコミット(追加した新しい変更も含みます)、git rebase --continueを実行します。これにより、ターミナルでデフォルトのエディターが開き、リベース中に編集したコミットメッセージが表示されます。 Page Navigation View。必要に応じてこのメッセージを変更できますが、今のところそのままにしておくので、保存してエディターを終了します。この時点で、Gitはすべてのコミットを再生します。編集したばかりのコミットの後に続き、ブランチHEADは元のコミットに戻り、コミットの1つに加えた新しい変更も含まれます。

リモートリポジトリにすでに存在するコミットを再度変更したため、git push --force-with-lease <remote_name> <branch_name>を使用してこのブランチを再度強制的にプッシュする必要があります。

状況3 :コミットを追加、削除、または組み合わせる必要があります

一般的な状況は、以前にコミットされたものを修正するためだけに複数のコミットを行った場合です。それでは、元のコミットと組み合わせて、可能な限り削減しましょう。

他のシナリオと同じように、インタラクティブなリベースを開始するだけです。

ここで、これらすべての修正をc22a3fa0c5c Render navigation partialに結合したいとします。必要なのは次のことだけです。

  1. 修正を上に移動して、最後に保持するコミットのすぐ下に配置します。
  2. pickを またはfixup

注:squashはコミットメッセージを説明に保持します。fixupは修正のコミットメッセージを忘れ、元のメッセージを保持します。

次のようになります。

変更を保存し、エディターを終了します、そしてあなたは」完了です!結果の履歴は次のとおりです。

以前と同様に、今必要なのはgit push --force-with-lease <remote_name> <branch_name>そして変更がアップしています。

squashfixupdropと書くか、その行を削除します。

競合を回避する

競合を回避するには、必ずコミットしてください。 「タイムラインを上に移動することは、それらの後に残されたコミットによって触れられた同じファイルに触れていません。

ヒント:簡単な修正

修正するコミットが正確にわかっている場合は、コミットするときに、「修正1」、「修正2」、…、の適切な一時的な名前を考えて脳のサイクルを無駄にする必要はありません。 「修正42」。

ステップ1:--fixup

に会う変更をステージングした後、修正が必要なものは何でも修正します。 Gitが次のようにすべての変更をコミットするだけです:

(これはコミットc22a3fa0c5c Render navigation partialのハッシュであることに注意してください)

これにより、次のコミットメッセージが生成されます:fixup! Render navigation partial

ステップ2:そしてサイドキック--autosquash

簡単なインタラクティブリベース。 gitfixupを適切な場所に自動的に配置させることができます。

git rebase -i 4155df1cdc7 --autosquash

履歴は次のように表示されます:

準備ができました確認して続行します。

冒険心がある場合は、非インタラクティブなリベースを行うことができますgit rebase --autosquashただし、危険な生活が好きな場合に限ります。 「適用される前に作成されたスカッシュを確認する機会がありません。

状況4:Gitのコミット履歴が意味をなさないので、新たなスタートが必要です!

「大規模な機能に取り組んでいる場合、頻繁にコミットされるいくつかの修正とレビューフィードバックの変更があるのが一般的です。ブランチを絶えずリベースする代わりに、開発が終了するまでコミットのクリーンアップを残すことができます。

これは、パッチファイルの作成が非常に便利な場所です。実際、パッチファイルは、コラボレーション中に電子メールでコードを共有するための主要な方法でした。 GitLabのようなGitベースのサービスが開発者に利用可能になる前の大規模なオープンソースプロジェクトで。そのようなブランチが1つあると想像してください(例:add-page-navigation)。ここには、根本的な変更を明確に伝えていないコミットがたくさんあります。すべてのパッチファイルを作成する方法は次のとおりです。このブランチで行った変更:

  • パッチファイルを作成する最初のステップは、ブランチにmasterブランチであり、同じものと競合することはありません。
  • チェックされている間、git rebase masterまたはgit merge masterを実行できます。 add-page-navigationブランチに出て、masterからブランチへのすべての変更を取得します。
  • 次に、パッチファイルを作成します。 ; run git diff master add-page-navigation > ~/add_page_navigation.patch
    • コマンドの内訳:ここでは、Gitのdiff機能を使用して、masterブランチとadd-page-navigationブランチ、および出力を(>シンボルを介して)私たちの中でerホームディレクトリ(通常、* nixオペレーティングシステムでは~/)。
  • このファイルを保持するパスを指定できます。で、ファイル名と拡張子は任意です。
  • コマンドを実行してエラーが表示されなくなると、パッチファイルが生成されます。
  • チェックアウトmasterブランチ; git checkout masterを実行します。
  • ローカルリポジトリからブランチadd-page-navigationを削除します。 git branch -D add-page-navigationを実行します。作成したパッチファイルにこのブランチの変更がすでにあることを忘れないでください。
  • 同じ名前で新しいブランチを作成します(masterがチェックアウトされている間)。 git checkout -b add-page-navigationを実行します。
  • この時点では、これは新しいブランチであり、変更はありません。
  • 最後に、適用します。パッチファイルからの変更; git apply ~/add_page_navigation.patch
  • ここでは、すべての変更がブランチに適用され、すべての変更がコミットされていないように見えます。完了しましたが、実際にはブランチでコミットされた変更はありませんでした。
  • これで、個々のファイルまたは影響範囲ごとにグループ化されたファイルを、簡潔なコミットメッセージで必要な順序でコミットできます。

以前の状況と同様に、基本的にブランチ全体を変更したので、強制的にプッシュするときが来ました。

結論

Gitを使用した日常のワークフローで発生する最も一般的で基本的な状況について説明しましたが、Gitの履歴を書き換えることは非常に大きなトピックであり、慣れてくると 上記のヒントでは、Gitの公式ドキュメントでこのテーマに関するより高度な概念を学ぶことができます。 Happy git “ing!

Unsplashのpanxiaozhenによる写真

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です