2016-04-18 28 views
2

これは少し長いですが、面白い問題かもしれません。Git Merge vs Rebase - 競合の解決

我々は最近、いくつかの小さなプロジェクトでそれを使用して、今、私たちが実際にそれ以上の関連するプロジェクトを使用している開始するには、管理人の抵抗の多くにもかかわらず、私たちの会社ではgitを使用し始めました。

私はいつもマージする前にリベースをしようとするが、つい最近、私たちは、このアプローチの問題点を発見しました。

あなたは、ファイルFを持っていて、以下のGitの歴史を持っている想像:

(master)  F -- F''1 
       \ 
(feature)  \- F'1 -- ... -- F'X 

、あなたは機能ブランチのリベースを行うと、最初の紛争の解決時に、あなたが実際にFからの変化を続ければ'1とF'1の場合、ファイルFのXの競合を手動で解決する必要があります。なぜなら、gitは自動的にそれらを解決できないからです。 逆に、(リベースなしで)マージを行っただけでは、1つの(大きな)コンフリクトを解決する必要があります。これは、本当に面倒な作業になる可能性があるため、リベースの実際の価値に疑問を呈しました。

私は何かを見逃しているのですか、これはまさにそれですか? 1つのファイルに対して30のコミットがある場合、それぞれのコミットをすべて実行し、手動で競合を解決する必要があります。この状況に対処するより適切な方法はありますか?

私は非常によく説明しなかった場合、私は申し訳ないけど、私はダミーのリポジトリに言及していると私はあなたが私を悩ませているものを得ると思うの手順を再現しようとすることができます。

+0

torekの回答を受け入れるのはどうですか? –

答えて

5

あなたは正しいです:通常は同じ方法で、再解決の競合を維持する必要があります。

git rerereと呼ばれるこれを行うための自動化のノブは、しかし、があります。 3つの -sは、の再の使用の再のコードの再のソリューションです。

これは、コンフリクトが発生するたびに解決されたバージョンgit addが発生すると、元のコンフリクト(行番号を引いたもの)と一部のファイルの解像度(実際にはリポジトリ)。次に、競合を通知する前に、マージコードは元の競合がすでに解決に関連付けられているかどうかを確認します。そうであれば、競合する領域をその解決策に置き換えます。

競合を記録する前に回線番号が削られているため、定期的な競合を常に処理するとは限りません。 (これは、周囲のコンテキストが変更されると失敗します。これは競合/解決のペアのハッシュIDを変更するためです)。

同じように見えますが遠く離れてファイル内で発生するので、実際には同じ矛盾ではありません(これはテンプレートyコードで発生する傾向があります)。すべての競合と解決策が記録されるので、多くの解決策を蓄積し、誤ったマッチを得ることができます。 Gitは記録された決議を60日以内に期限切れにすることでこれを処理しようとします(わずか15日以内に未解決の紛争もあります)。

最初の競合を作成する前にrerereを有効にして、git add - 解決を有効にする必要があります。これはちょっと迷惑なことです。しばしばあなたが(おそらく、私が)rerereを早めに有効にしておくべきであることを発見して、今は遅すぎます。私は、すでに解決している以前のマージまたはリベースを繰り返すスクリプトを書いて、既存の解決法を使って、rerereエンジンを準備するrerere-replayにフィードしたいと思っています。 (このスクリプトの明白な名前はgit-rererere ... :-))

+0

私はこの問題の回数を処理しました。私はいつも以下のアプローチを試みました。私の支店に30のコミットがあり、プルリクエストがレビューされて、それが良いことがあったとしましょう。最後の部分はマスターとリベースすることです。まず、機能ブランチの30個のコミットを1つのコミットに入れて、その後、すべての競合を何度も解決する必要はありませんでした。 –

+0

"最初の競合を作成する前にrerereを有効にする必要があります...">なぜ 'git config --global rerere.enabled true'ですか? –

+1

@MuhammadShoaib:すべての履歴を効果的に破壊するように、偉大な –

関連する問題