web-dev-qa-db-ja.com

レビュー中の別のブランチに依存するブランチで作業する

Gitは以下のシナリオにどのように対処しますか?

私は2つの部分に分割されたタスクを持っています:バックエンドタスクとフロントエンドタスク。バックエンドの変更をマージするプルリクエストを作成し、それがマージされる(およびフィードバックに対処する)のを待ちます。待機中は、フロントエンドの変更はバックエンドの変更に依存しているため、masterブランチではまだ使用できないため、実際には変更できません。

まだレビューされている間に、バックエンドの変更ブランチからフロントエンドの変更ブランチへの変更を取り込む最良の方法は何ですか?

79
sul4bh

しばらくお待ちください、マージをスキップします

このアプローチでは、notfeature_afeature_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_amasterにマージされたらすぐに、新しいmasterを取得し、最後にfeature_aをリベースします。

    git checkout master
    git pull Origin master
    git checkout feature_b
    git rebase --onto master feature_a feature_b
    

    この最後のリベースは、feature_acommit(masterにマージされたため、現在は無関係)からぶら下がっているすべてのコミットをmasterに直接移植します。 feature_bmasterからの単純な標準ブランチになりました。

編集:コメントからインスピレーションを得て、少し前に:両方機能に影響する変更を加える必要がある場合は、必ずfeature_aに追加してください(次に、図のようにリベースします)。 。 Do not両方のブランチで2つの異なるコミットで実行します。 feature_afeature_bの履歴の一部であるため、2つの異なるコミットで1つの変更を行うことは意味的に間違っており、後で不要なコードの競合または「復活」につながる可能性があります。

57
AnoE

私も時々この問題を抱えています。 Gitは非常に柔軟です。これを行う方法の1つを次に示します。

最初のブランチfeatureAをレビューします。

2番目のブランチfeatureBは開発中であり、featureAブランチのコードに依存しています。

featureAブランチをfeatureBブランチにマージします。

featureAブランチに変更を加えた場合は、featureAブランチをfeatureBブランチに再度マージして、変更を組み込む必要があります。

また、最初にfeatureAをメイントランクにマージする必要があります。そうしないと、featureBをメイントランクにマージするときに、誤ってfeatureAもマージされます。 featureAがメイントランクにマージされると、featureAブランチはメイントランクにのみ依存するため、featureBブランチを削除できます。

私の機能ブランチが相互に依存していないが、時には依存していて、それに合わせてロールする必要がある場合は、これを好みます。

43
Matt

すべての機能ブランチが依存し、変化し続けるブランチがすでにあります。これはmasterと呼ばれます。

機能ブランチがmasterと同期を保つための一般的な方法は、を維持することです。 masterが変更された場合、通常はgit fetch Origin master:master && git rebase masterブランチの作業ディレクトリ。

同じことを別の機能ブランチで行うことができます。それをフェッチし、その上にリベースし続けます。

何らかの理由で変更を別のブランチに移動する必要がある場合は、yourコミットをチェリーピックすることができます。コミットは他のブランチのコミットと混合されることはありません。

30
9000

この場合、フロントエンドタスクがバックエンドコードに重要な依存関係を持ち、バックエンドが確定してマスターで承認される前にフロントエンドで作業を開始したい場合は、フロントエンドタスクを、マスターのフロントエンドを分岐するのではなく、バックエンドの分岐。

存続期間が長い機能ブランチは、マスターからの変更を時々マージする必要があります(「レビュー、qa、マージ-の一部としてではなく、機能ブランチの開発作業の一部としてマージまたはセマンティックの競合を調整するために」マスターする」プロセス)。つまり、フロントエンドブランチでそれを行い、バックエンドの作業がマスターとして承認されると、レビュー/承認の一部としてバックエンドに加えられた小さな変更が、同じルートで自動的に取得されます。マスターで他のコード変更を取得します。

バックエンドブランチにさらに多くの作業が必要であることが判明し、一定期間にわたって変化し続けるbeforeマスターにマージされる場合(たとえば、レビュー中に大きな問題が見つかった場合)、次のようになります。おそらく、定期的にバックエンドブランチからフロントエンドブランチに直接マージする必要があります(そのため、すべてのフロントエンド作業を古いバックエンドコードに基づいて行わないでください)。これは、両方の機能を実行している唯一の開発者であれば簡単です(自分で大きな変更を加えたかどうかを知っているので)。コミュニケーションを取り続ける必要があります(一方が他方に重大な依存関係があるタスクを並行して処理している場合は、とにかくそれが必要です)。

バックエンドブランチ全体を破棄する必要があり、マージしないことがわかった場合(これはめったに起こらないかなり大きな取引になると思われます)、マスターから離れた新しいブランチへのコミットを選択しますバックエンド作業なしで、またはすべてのバックエンドコードをフロントエンドブランチから削除するリバースコミットを適用します。しかし、私が見ることができるように、あなたが投げているバックエンドを置き換えるものを理解し、次に何をすべきかを決めるまで、フロントエンドの作業を一時停止する可能性が高くなります。

5
Ben

ここには問題はありません。

これは、masterブランチで毎回すでに行われています。これは、機能が開発されてマージされる間、変化し続けます。

したがって、具体的な例では、最初にfeature_xxx_backendブランチを作成し、バックエンドの変更を開発します。これが完了すると、ブランチはレビューできる状態になり、レビューが完了するとmasterにマージされます。

したがって、別のブランチfeature_yyy_frontendを開始するだけです。おそらくfeature_xxx_backendから直接分岐して、これらの変更がすでに支店にあるようにする必要があります。次に、ブランチがmasterであるかのように、フロントエンド機能を開発します。

feature_xxx_backendブランチが変更されたとき。レビュー中に対処する必要があることがあるので、これらの変更を行ってfeature_yyy_frontendブランチにマージします。次に、フロントエンドブランチに進みます。

バックエンドブランチのレビューが完了すると、masterにマージされます。この時点で、feature_yyy_frontendブランチをmasterrebaseブランチするのが賢明です。そのため、レビュー担当者はnewこのブランチがmasterに貢献する変更であり、バックエンドに対して行われた変更(すでに承認済み)を再確認する必要はありません。

これは、2つ、3つ、またはそれ以上の依存ブランチがある場合にも実行できます。依存している機能ブランチが2つある場合は、両方の機能がマージされた派生ブランチを作成します。そこからブランチし、3番目の機能を開発して、それぞれの変更時に両方の機能ブランチをマージします。両方の機能が完了し、派生ブランチのいずれかにマージされる場合は、そのベースにリベースするか、マスターにマージされる場合はマスターにリベースします。

リベース(上記で提案したとおり)は非常に強力であり、変更のクリーンなログを維持するのに役立ち、レビューがはるかに簡単になります。

2
Polygnome

Polygnomeが述べたように、実際にはマスターの代わりにフロントエンドブランチをバックエンドブランチにマージできます。現在使用しているブランチのセットアップでも、次のように簡単に実行できます。

git checkout frontend
git merge backend

または単に

git merge backend frontend

ただし、バックエンドの変更が受け入れられず、さらに作業が必要な場合は、競合を回避するために、バックエンドの更新をフロントエンドにマージする必要があることに注意してください。変更がマスターに受け入れられると、フロントエンドをマスターにリベースして、バックエンドマージコミットを取り除くことができます。

技術的にはリベースですべてを行うこともできますが、それはフロントエンドブランチのコミット履歴を台無しにします。私がどこから来たのか、これは悪い習慣だと考えられています。 YMMV

2
Joris Meys

ここでのほとんどの回答は、2番目のブランチから最初のブランチへの変更をマージするプロセスを正しく説明していますが、解決する必要のある競合の量を最小限に抑える方法については触れていません。

個別に確認したい2組の大きな変更(featureAfeatureBなど)がある場合は常に、マージすることを意図していないが、PoCに関する早期のフィードバックを収集するためのPRを作成します。 featureA

人々はそれをすばやくレビューできるようになり(単なるPoCです)、その目的は一般的な設計またはアプローチを検証することです。

次に、機能Aで作業を続け、そのプルリクエストを作成して分岐し、機能Bで作業できます。

大きな違いは、featureAが根本的に変更されないことを期待できることです。設計とアプローチはすでに検証されています。コードのレビューと必要な変更は、「別のアプローチが必要です」ではなく、微妙でローカルな場合があります。これにより、選択した方法に関係なく、後でfeatureBのコードのマージfeatureAを実行するために必要な作業量を最小限に抑えることができます。

1
Alpha