2016-04-02 11 views
1

次のシナリオでは、手動による解決が必要な競合が発生しますか?潰れたコミットが元のコミットと競合します

  1. あなたはD、E

  2. PRが見直されている間、あなたはローカルでその同じ機能ブランチで作業を続け、より多くの追加は、F、Gをコミットコミット含む、PRのための機能ブランチを提出、H.

  3. ある時点で、PRは承認され、マスターにマージされます。 Commits D/E on master have been replaced with commit X due to squashing。コミットD、E、F、G、Hを含むローカルブランチとコミットXを含むマスターブランチがあります。

  4. コミットF/G/Hをマスターにマージします。したがって、ローカルブランチ(D/E/F/G/Hを含む)をマスター(Xを含む)にマージしようとします。

コミットD/EとXはコードの同じ行に触れますが、コミットIDは異なります。 D/Eを一緒に見てXと比較すると、D/Eは同じです。しかし、Dを単独で見てXと比較すると、一般的に変更された行には多くの違いがあります。

マージの競合なしに{D/E - X}をマージするのに十分なほどスマートですか?あるいは、上記のように手作業による介入を必要とする多数の紛争が生じるだろうか?

+5

お試しください。 –

答えて

2

私はいくつかのgit実験をローカルで実行し、質問に記載されているワークフローの手順を複製しました。残念ながら、答えは「はい」と思われます。 git squashを使うと、何をやっているのか細心の注意を払わなければ、多くのマージ競合が発生します。

私はこれについて広範囲にわたってthis blog postに書いています。


上記の問題は、あなたが単純なマージを行っても、かすれがなくても発生しませんでした。その場合、マージ後、マスタとローカルブランチの両方にコミットD-Eが含まれます。したがって、次にローカルのD-E-F-G-Hブランチをマージしようとすると、gitはマスターの上にF-G-Hを適用してマージを実行します。

しかし、私たちはスカッシュをしたので、これはgitを混乱させます。残念ながら、コミットF-G-HはXで修正されたコードと同じ行を変更するため、結果のdiffはマージの競合で失敗します。

この問題を解決するにはいくつかの潜在的な方法:

  1. ブルートフォース:それを吸うと、手動ですべての競合を解決します。

  2. プルリクエストを送信したら、プルリクエストに含まれるコミットの上に追加のコミットを作成しないでください。プルリクエストのコミットは、gitの観点から消えていくので、あなたはそれらに依存したくありません。残念ながら、これは、あなたが提出したものの上で実行したい任意の改良が、プルリクエストが承認され、マージされるまで待つ必要があることを意味します。

  3. 以前のプルリクエストの上で改良を加えた場合は、以前のプルリクエストをマージすることを許可しないでください。代わりに、更新されたブランチを使用して新しいプルリクエストを送信するか、既存のプルリクエストをすべての詳細設定で上書きします。残念なことに、これはプル・リクエスト・プロセスをオール・オア・ナイン・アフェアにします。理想的には、最初のプルリクエストと追加のリファインメントを段階的に承認/マージすることができます。代わりに、競合を避けるために、あなたは一気に全部をマージするか、何もマージしないように強制する必要があります。

  4. あなたの以前のPRがマージされたとし、あなたが今マスターに併合したいと思う新たな改良があるとします。ブランチ全体をマスターにマージするのではなく、作成したインクリメンタルなコミットをチェリーピックし、それらのチェリーピックされたコミットだけをマージします。したがって、上記の例では、D-E-F-G-HをXにマージしようとするのではなく、F-G-HをコミットしてXの上に適用し、結果のブランチでプルリクエストを作成します。これはうまく動作し、すべての競合を回避し、いつでも/あなたが望むペースで開発作業を行うことができます。残念ながら、D-E == Xという事実を手動で追跡する必要があり、F-G-Hを手動でチェリーピックして適用する必要があります。これは、より多くの時間と認知努力を必要とします。また、チェリーピッカーを多すぎる(とにかく紛争を起こす)、またはチェリーピッキングを少なめにする(そして重要な変更が見落とされる)ことによって、このステップを混乱させるのも簡単です。

  5. githubのメタル機能を使用しないでください。いずれのスカッシュもプルリクエストを提出する前に、ローカルでコミットします。または、まっすぐに抜かずにプルリクエストをマージしてください。これは、ほとんどのプロジェクトの現状であり、そこにはすべての利点/欠点があります。

このように、マージする前にすべてのコミットを抑制するのに実際の問題やコストがあります。上記の解決策のどれも完全ではありません。私は、上記のうちのどれがすべての悪の中で最も小さいか分からない。しかし、私はあなたにこの問題についてもっと深く考えさせて、この新しい素晴らしいGitHub機能を利用する際の注意点を理解してほしいと思っていました。

+1

問題を引き起こすのはスカッシュ "マージ"ではなく、マージが全くないという事実です。あなたの新しい仕事が組み込まれたら、 'DEFGH'シーケンスを' F'-G'-H''シーケンスにリベースする必要があります。そのシーケンスの親( 'F''の親、つまり' '新しい' 'X''コミット。どちらが迷惑だが、できない。 (これはgithubに固有のものではありませんが、git:mergeの一般的な原則は* merge base *を使用して差分を計算し、「マージ」はマージではないため、マージベースには影響しません) – torek

+0

I同意する。あなたが説明しているのは、上記の提案#4と概念的に似ています。手動でコミットし、新しいブランチに適用します。あなたが言及したように、それは実行可能ですが、開発者がgitログを解析して、関心のある特定のgit-commitを探し出す必要があることは残念です。 – RvPr

2

Gitは共有ベース以降の各チップの変更を比較します。同一の変更によって競合が発生しません。

関連する問題