6

私たちのgit開発ワークフローでは、トピックブランチは、マージされるまで最新のマスターに基づいて継続的にリベースされます。

ただし、新しい開発者がトピックブランチを作成し、マスターをトピックブランチにいくつかマージして、それらを最新の状態に保ちました。

    A---B---C---D---E topic
   /       /   /
  F---G---H---I master

このトピックブランチをマスターにマージすることは完全に正しいでしょうが、それは非常に厄介な歴史をもたらします。--no-ffこれらのトピックブランチを、1回のマージコミットでマスターにクリーンにマージできるクリーンな線形リベース履歴に変換したいと思います。

                A'---B'---E' topic
               /
  F---G---H---I master

理想的には、CやDなどのトピックマージコミットですでに利用可能なマージ競合解決情報を自動的に適用しながら、トピックブランチのコミットをそのまま取得してリベースを実行できるgit-fuがいくつかあります。

「gitdiffmaster..topic」のパッチを適用してから、リベースを使用して逆方向に作業し、単一のパッチを手動で個々のコミットに分割できることはわかっていますが、よりシンプルでエレガントなアプローチはありますか?

私はまっすぐに試してみましたがgit rebasegit rebase -p運が悪かったのです。

4

2 に答える 2

4

次のプロセスは、完全ではありませんが、かなりうまく機能しているようです。いくつかのマイナーな競合解決が必要になる場合があります-以下を参照してください。

  1. まだ行われていない場合は、マスターからの最終マージを実行して、トピックブランチが最新のマスターで最新であることを確認します。

    git checkout topic
    git merge master
    
  2. マージを除外することにより、トピックブランチの履歴を簡素化します。

    git log --no-merges
    
  3. 上記のログから、分岐点を決定します(最初のトピックブランチコミットの前のマスターでのコミット。コミットFである必要があります)。

  4. トピックブランチ--preserve-mergesマスターにリベースし、マージを無視して(これはデフォルトです。つまり、 /-pオプションを使用しないでください)、競合を解決します。

    git checkout master
    git rebase --onto HEAD F topic
    

    リベース中に、ファイルが競合する「両方の変更済み」状態になる競合が発生することがよくありましたが、競合マーカーが含まれていなかったため、競合を解決して続行するには単純git addgit rebase --continue十分でした。gitは以前の解決策を使用して競合を解決していたと思います。

    また、一部のより複雑なブランチでは、複数のgit rebase --onto HEAD ...コマンドが必要になるか、または代わりgit cherry-pickに個々のコミットを選択するために使用できます。手順2で示したログを確認し、範囲をHEADにリベースするか、必要に応じて個々のコミットを選択する可能性があります。

  5. 現在のHEADは、リベースされたトピックブランチを表すはずです。差分の結果が出力されないことを確認して、結果が元のトピックブランチと一致することを確認します。

    git diff topic..HEAD
    
  6. リベースされたトピックブランチ名にHEADという名前を付けます。

    git checkout -b rebased-topic
    
于 2012-06-20T06:53:57.300 に答える
1

ラマンの答えは私にとってはほとんどうまくいきましたが、ステップ4の周りにさらに詳細を追加したいと思いました。これは、私にとっては注意が必要でした。

もっと複雑なレポがあったのでこんな感じでした

        Q-R-S-T-U-V-W-X
       /   /     /   /
A-B-C-D-E-F-G-H-I-J-K

私はこれが欲しかった:

                      Q'-R'-S'-T'-U'-V'-W'-X'
                     /
A-B-C-D-E-F-G-H-I-J-K

うまくいったのはgit rebase --onto HEAD Q R、それから、それで、基本的に私がマージしgit rebase --onto HEAD S Uた場所の間のコミットの範囲をつかむことでした。ずっとこれをしている間、私は頭が離れた状態だったので、それを見ても心配しないでください。マージの競合が数回ありましたが、それらはすべて、私が期待していた正当な競合でした。mastertopic

最後に、私はほぼ正しく見えるブランチを持っていました(Ramanの答えのステップ6)が、何らかの理由で、実際にコミットを移動するために再びマスターにリベースする必要がありました。なぜそうしなければならなかったのかわかりませんが、順調に進みました。

このようにすることは、基本的にはさくらんぼ狩りと同じだと思うので、代わりにそれを行う方が簡単かもしれません。

于 2015-04-08T23:24:36.327 に答える