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


65

gitは以下のシナリオの処理にどのように役立ちますか?

タスクは、バックエンドタスクとフロントエンドタスクの2つの部分に分かれています。プルリクエストを作成してバックエンドの変更をマージし、マージされるのを待ちます(そしてフィードバックに対処します)。待っている間、フロントエンドの変更はバックエンドの変更に依存しており、マスターブランチではまだ利用できないため、フロントエンドの変更を実際に処理することはできません。

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


14
通常、バックエンドプロジェクトのインターフェイスは明確に定義する必要があります。そのため、フロントエンドの実装を開始するときに、モックアップを使用できるので、バックエンドのロジックがまだレビューされていても気にする必要はありません。
Herrb Derb

17
@HerrDerbああ甘い夏の子...
gardenhead

4
まだレビューされていないバックエンドコードに対してそれを記述できないのはなぜですか?
user253751

あなたのチームは、この状況を処理するための何らかの合意されたテクニックを持っていますか?そうでない場合、これはかなり一般的な状況であるため、おそらくこのようなものに同意する必要があります。
ラドゥマーゼア

なにもない。それが私がこの質問をした理由です。とても良い提案がありました。提案を試してみて、それらがどのように機能するかを確認します。
sul4bh

回答:


42

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

最初のブランチfeatureAは審査中です。

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

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

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

また、featureA最初にメイントランクにマージfeatureBする必要があります。そうしないと、メイントランクにマージするときに、誤ってマージすることになりますfeatureA。一度featureAあなたが取り除くことができ、メイントランクにマージされるfeatureAよう枝featureBだけになりましメイントランクに依存します。

私の機能ブランチが互いに依存していないが、時々依存しているので、あなたはそれを動かさなければならないときにそれを好む。


意味あり。これは、マージのを元に戻すために許可していfeatureA上にfeatureB必要であれば?
sul4bh

8
元に戻す操作はありませんが、@ 9000が述べているように、featureA最初からやり直す必要がある場合は、新しいブランチを作成し、そこから目的のコミットを選択できます。Gitブランチを使い捨てと考えるのは良いことです。それらは安価で簡単で、いつでも新しいブランチを作成できます。featureBわからないことを試したい場合はブランチからテストブランチを作成し、うまくいかない場合はそれを廃棄し、うまくいかないfeatureB場合はブランチにマージします。
マット

9
マージすると、ロールバックが困難になる(不可能ではない)混乱が生じます。私はチェリーピックまたはリベースをやり直します(つまり、featureBのベースでfeatureAのすべてをチェリーピックします)。9000の回答を参照してください。
-Pierre.Sassoulas

1
これは、誰かがfeatureAとのfeatureBのために変更されたどのようなコードを理解したいと考えていたときに来て、長年にわたって問題となる複雑な歴史を作成
イアン

2
featureAが更新された場合、のfeatureBはリベースする必要がありませんマージ
リンドンホワイト

40

待って、マージをスキップ

このアプローチのために、あなたはないではない、あなたをマージするfeature_afeature_b繰り返し。

リベースは他の回答でも言及されていますが、リベースはにリベースするためだけですmaster。あなたのケースでやりたいことは:

  • feature_bから開始feature_a、すなわち:

    git checkout feature_a
    git checkout -b feature_b
    
  • feature_aマージされるのを待っている間に変更するたびにmasterリベース feature_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コミットからぶら下がっているすべてのコミット(現在はマージされているため無関係になりますmaster)をに直接移植しmasterます。あなたはfeature_b今から右に行く簡単な、標準のブランチですmaster

編集:コメントからヒントを得て、少し頭を上げてください:両方の機能に影響する変更を加える必要がある場合は、必ずそれを行ってくださいfeature_a(そして、次に示すようにリベースしてください)。魅力的な場合でも、両方のブランチで2つの異なるコミットを行わないでください。feature_a歴史の一部であるfeature_b二つの異なるコミットで単一の変更は、意味的に間違っていると、おそらく後に、不要なコードの競合や「復活」につながる有します。


2
上のリベースでfeature_a複数回、後でとき、問題が発生する可能性がありfeature_a、それ自体が、その間にリベースされました。実行した結果、git checkout feature_b; git rebase feature_a競合が発生したり、の新しい変更を元に戻すコミットを含むおかしなコミットが発生する可能性がありfeature_aます。これは通常--interactive、他のブランチの古いバージョンから取得したコミットを使用してスキップすることで解決できます(最近これを何回かしなければなりませんでした)。
-maaartinus

@maaartinus、ヘッズアップのおかげで、私は自分でそのような問題に遭遇していません。rebase単純なよりも多くの個々のステップを行いmerge、それが競合を作成するために見た目が高い可能性が確かにあります。一方merge、この場合、意味的にはまったく間違っています。
-AnoE

私は、merge同様の、またはより悪い問題を抱えていると思います(競合は、望ましくない変更を取得するほど悪くはありません)。ブランチは、関連のない多くの変更(論理的には別のブランチに属する)が先行する、必要な変更のシーケンスとして表示されます。同じブランチで繰り返しリベースするときは、関係のない変更を削除します(とにかく更新された形で)、それはうまく機能します。
-maaartinus

1
@maaartinus、これに関する小さな補遺を追加しました(2つの異なるコミットではなく、ベースブランチのみで両方のブランチに行く必要がある変更を一貫して行うため)。
-AnoE

素敵なテクニック。それは私がいつもそれを行う方法でもあります。git rebase --ontoFTW:D
ラドゥMurzea

29

すべての機能ブランチが依存し、変化し続けるブランチが既にあります。という名前masterです。

機能ブランチが同期を保つための典型的な方法は、機能ブランチを常に最新の状態masterに保つことです。ときに変更、あなたは通常、あなたのブランチの作業ディレクトリにあります。mastergit fetch origin master:master && git rebase master

別の機能ブランチでもまったく同じことができます。それを取得し続け、その上にリベースします。

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


しかし、私は、機能bは機能aにあるコードを必要とし、マスターからの分岐はあまり役に立たないだろうと思います。どこから始めればいいですか?feature-aから分岐し、feature-aがmasterと統合されるまでそれらを同期させ、その後masterからfeature-bにリベースする必要がありますか?
シナエステ

@Sinaesthetic:もちろんをベースにfeature-bしてfeature-afeature-a変化するたびにリベースを行うことができます。これは、大きな変更を観察可能にする典型的な方法です。それをpart-A(offに基づいてmaster)、part-B(offに基づいてpart-A)、必要に応じてさらに分割します。次に、各パーツに対してプルリクエストを行うと、レビュー担当者は、論理的にグループ化された小さなピースを簡単に見ることができます。
9000

PRの観点から、part-bをpart-aとpart-bをmasterでリベースする場合、問題になりますか?私は自分の変更がpart-aの変更をpart-bの変更として表示しないことを確認したいだけです。また、マージとリベースの場合、part-b PRにどのような影響がありますか?効果を理解すると思うたびに、いくつかの異なる結果が得られますlol
Sinaesthetic

5

この場合、フロントエンドタスクがバックエンドコードに重大な依存関係を持ち、バックエンドが完成してマスターで受け入れられる前にフロントエンドで作業を開始したい場合は、単に、フロントエンドタスクを、マスターでフロントエンドを分岐するのではなく、バックエンドの分岐。

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

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

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


2

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

masterブランチには毎回これがす​​でにあります。これは、機能が開発されてからマージされるまで変化し続けます。

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

したがって、別のブランチを開始するだけfeature_yyy_frontendです。おそらくブランチから直接変更したいので、ブランチにfeature_xxx_backend既にこれらの変更があるようにしたいでしょう。その後、ブランチがそうであるかのように単にフロントエンド機能を開発しmasterます。

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

バックエンドブランチのレビューが完了すると、にマージされmasterます。この時点で、ブランチをにリベースすることをお勧めfeature_yyy_frontendますmaster。これにより、レビュー担当者は、このブランチが貢献する新しい変更のみをレビューするmaster必要があり、バックエンドに加えられた変更(既に承認済み)を再レビューする必要はありません)。

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

リベース(上記で提案)は非常に強力で、変更のログをきれいに保つのに役立ち、レビューをはるかに簡単にします。


2

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

git checkout frontend
git merge backend

または単に

git merge backend frontend

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

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


「奇妙なことに、マスターの代わりにフロントエンドブランチをバックエンドブランチに実際にマージできることを誰も言及していなかったこと:」これ、例えば私の答えですでに言及されています。
ポリノーム

@Polygnomeフロントエンドは、バックエンドから直接分岐する必要はありません。両方をマスターから分岐させることもできますが、マージすることはできます。あなたの答えは実際にはそれについて言及していません。
ジョリスメイズ

実際、私の答えは、あなたがバックエンドから直接分岐することを示唆していません、それはたぶん行くべきルートだと言っています(これらの変更をフロントエンドブランチにマージするので)。
ポリノーム

@Polygnomeそれから私はあなたの答えを誤解しました。特にあなたのために更新:-)
ジョリスメイズ

誰がこれを支持したかはわかりませんが、どこが間違っているのか教えてください。そうすれば、私も何かを学ぶことができます。
ジョリスメイズ

1

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

個別に確認する2つの大きな変更セット(featureAおよびなどfeatureB)がある場合は常に、マージするつもりはないが、PoCの早期フィードバックを収集するPRを作成しますfeatureA

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

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.