Gitは以下のシナリオにどのように対処しますか?
私は2つの部分に分割されたタスクを持っています:バックエンドタスクとフロントエンドタスク。バックエンドの変更をマージするプルリクエストを作成し、それがマージされる(およびフィードバックに対処する)のを待ちます。待機中は、フロントエンドの変更はバックエンドの変更に依存しているため、masterブランチではまだ使用できないため、実際には変更できません。
まだレビューされている間に、バックエンドの変更ブランチからフロントエンドの変更ブランチへの変更を取り込む最良の方法は何ですか?
このアプローチでは、notfeature_a
をfeature_b
に繰り返しマージする必要があります。
リベースは他の回答でも言及されていますが、master
にリベースする場合に限られます。あなたがあなたのケースでしたいことは:
feature_b
からfeature_a
を開始します。
git checkout feature_a
git checkout -b feature_b
master
にマージされるのを待っている間にfeature_a
が変更されるたびに、rebasefeature_b
を実行します。
... commit something onto feature_a ...
git checkout feature_b
git rebase feature_a
最後に、feature_a
がmaster
にマージされたらすぐに、新しいmaster
を取得し、最後にfeature_a
をリベースします。
git checkout master
git pull Origin master
git checkout feature_b
git rebase --onto master feature_a feature_b
この最後のリベースは、feature_a
commit(master
にマージされたため、現在は無関係)からぶら下がっているすべてのコミットをmaster
に直接移植します。 feature_b
はmaster
からの単純な標準ブランチになりました。
編集:コメントからインスピレーションを得て、少し前に:両方機能に影響する変更を加える必要がある場合は、必ずfeature_a
に追加してください(次に、図のようにリベースします)。 。 Do not両方のブランチで2つの異なるコミットで実行します。 feature_a
はfeature_b
の履歴の一部であるため、2つの異なるコミットで1つの変更を行うことは意味的に間違っており、後で不要なコードの競合または「復活」につながる可能性があります。
私も時々この問題を抱えています。 Gitは非常に柔軟です。これを行う方法の1つを次に示します。
最初のブランチfeatureA
をレビューします。
2番目のブランチfeatureB
は開発中であり、featureA
ブランチのコードに依存しています。
featureA
ブランチをfeatureB
ブランチにマージします。
featureA
ブランチに変更を加えた場合は、featureA
ブランチをfeatureB
ブランチに再度マージして、変更を組み込む必要があります。
また、最初にfeatureA
をメイントランクにマージする必要があります。そうしないと、featureB
をメイントランクにマージするときに、誤ってfeatureA
もマージされます。 featureA
がメイントランクにマージされると、featureA
ブランチはメイントランクにのみ依存するため、featureB
ブランチを削除できます。
私の機能ブランチが相互に依存していないが、時には依存していて、それに合わせてロールする必要がある場合は、これを好みます。
すべての機能ブランチが依存し、変化し続けるブランチがすでにあります。これはmaster
と呼ばれます。
機能ブランチがmaster
と同期を保つための一般的な方法は、上を維持することです。 master
が変更された場合、通常はgit fetch Origin master:master && git rebase master
ブランチの作業ディレクトリ。
同じことを別の機能ブランチで行うことができます。それをフェッチし、その上にリベースし続けます。
何らかの理由で変更を別のブランチに移動する必要がある場合は、yourコミットをチェリーピックすることができます。コミットは他のブランチのコミットと混合されることはありません。
この場合、フロントエンドタスクがバックエンドコードに重要な依存関係を持ち、バックエンドが確定してマスターで承認される前にフロントエンドで作業を開始したい場合は、フロントエンドタスクを、マスターのフロントエンドを分岐するのではなく、バックエンドの分岐。
存続期間が長い機能ブランチは、マスターからの変更を時々マージする必要があります(「レビュー、qa、マージ-の一部としてではなく、機能ブランチの開発作業の一部としてマージまたはセマンティックの競合を調整するために」マスターする」プロセス)。つまり、フロントエンドブランチでそれを行い、バックエンドの作業がマスターとして承認されると、レビュー/承認の一部としてバックエンドに加えられた小さな変更が、同じルートで自動的に取得されます。マスターで他のコード変更を取得します。
バックエンドブランチにさらに多くの作業が必要であることが判明し、一定期間にわたって変化し続けるbeforeマスターにマージされる場合(たとえば、レビュー中に大きな問題が見つかった場合)、次のようになります。おそらく、定期的にバックエンドブランチからフロントエンドブランチに直接マージする必要があります(そのため、すべてのフロントエンド作業を古いバックエンドコードに基づいて行わないでください)。これは、両方の機能を実行している唯一の開発者であれば簡単です(自分で大きな変更を加えたかどうかを知っているので)。コミュニケーションを取り続ける必要があります(一方が他方に重大な依存関係があるタスクを並行して処理している場合は、とにかくそれが必要です)。
バックエンドブランチ全体を破棄する必要があり、マージしないことがわかった場合(これはめったに起こらないかなり大きな取引になると思われます)、マスターから離れた新しいブランチへのコミットを選択しますバックエンド作業なしで、またはすべてのバックエンドコードをフロントエンドブランチから削除するリバースコミットを適用します。しかし、私が見ることができるように、あなたが投げているバックエンドを置き換えるものを理解し、次に何をすべきかを決めるまで、フロントエンドの作業を一時停止する可能性が高くなります。
ここには問題はありません。
これは、master
ブランチで毎回すでに行われています。これは、機能が開発されてマージされる間、変化し続けます。
したがって、具体的な例では、最初にfeature_xxx_backend
ブランチを作成し、バックエンドの変更を開発します。これが完了すると、ブランチはレビューできる状態になり、レビューが完了するとmaster
にマージされます。
したがって、別のブランチfeature_yyy_frontend
を開始するだけです。おそらくfeature_xxx_backend
から直接分岐して、これらの変更がすでに支店にあるようにする必要があります。次に、ブランチがmaster
であるかのように、フロントエンド機能を開発します。
feature_xxx_backend
ブランチが変更されたとき。レビュー中に対処する必要があることがあるので、これらの変更を行ってfeature_yyy_frontend
ブランチにマージします。次に、フロントエンドブランチに進みます。
バックエンドブランチのレビューが完了すると、master
にマージされます。この時点で、feature_yyy_frontend
ブランチをmaster
にrebaseブランチするのが賢明です。そのため、レビュー担当者はnewこのブランチがmaster
に貢献する変更であり、バックエンドに対して行われた変更(すでに承認済み)を再確認する必要はありません。
これは、2つ、3つ、またはそれ以上の依存ブランチがある場合にも実行できます。依存している機能ブランチが2つある場合は、両方の機能がマージされた派生ブランチを作成します。そこからブランチし、3番目の機能を開発して、それぞれの変更時に両方の機能ブランチをマージします。両方の機能が完了し、派生ブランチのいずれかにマージされる場合は、そのベースにリベースするか、マスターにマージされる場合はマスターにリベースします。
リベース(上記で提案したとおり)は非常に強力であり、変更のクリーンなログを維持するのに役立ち、レビューがはるかに簡単になります。
Polygnomeが述べたように、実際にはマスターの代わりにフロントエンドブランチをバックエンドブランチにマージできます。現在使用しているブランチのセットアップでも、次のように簡単に実行できます。
git checkout frontend
git merge backend
または単に
git merge backend frontend
ただし、バックエンドの変更が受け入れられず、さらに作業が必要な場合は、競合を回避するために、バックエンドの更新をフロントエンドにマージする必要があることに注意してください。変更がマスターに受け入れられると、フロントエンドをマスターにリベースして、バックエンドマージコミットを取り除くことができます。
技術的にはリベースですべてを行うこともできますが、それはフロントエンドブランチのコミット履歴を台無しにします。私がどこから来たのか、これは悪い習慣だと考えられています。 YMMV
ここでのほとんどの回答は、2番目のブランチから最初のブランチへの変更をマージするプロセスを正しく説明していますが、解決する必要のある競合の量を最小限に抑える方法については触れていません。
個別に確認したい2組の大きな変更(featureA
とfeatureB
など)がある場合は常に、マージすることを意図していないが、PoCに関する早期のフィードバックを収集するためのPRを作成します。 featureA
。
人々はそれをすばやくレビューできるようになり(単なるPoCです)、その目的は一般的な設計またはアプローチを検証することです。
次に、機能Aで作業を続け、そのプルリクエストを作成して分岐し、機能Bで作業できます。
大きな違いは、featureA
が根本的に変更されないことを期待できることです。設計とアプローチはすでに検証されています。コードのレビューと必要な変更は、「別のアプローチが必要です」ではなく、微妙でローカルな場合があります。これにより、選択した方法に関係なく、後でfeatureB
のコードのマージfeatureA
を実行するために必要な作業量を最小限に抑えることができます。