この質問に重複としてフラグを立てました。他の回答で説明したことを書き
ますが、あなたの例を使用します。
このようなユースケースで私が使用するアプローチは、移動するすべてのブランチを 1 つの共通の人工ノードにマージしてから、rebase コマンドと--preserve-merges
オプションを使用することです。すべてのブランチをマージすると、 の最終的な入力パラメータとして使用される1 つのエンドポイントが公開rebase --onto
されます。通常、開始点は明白で、移動するサブツリーの起点です。
サブツリー endpointを取得するためにマージする場合、競合は明示的に回避する必要があります。したがって、マージ コマンドは、オプションを使用してそれらを自動的に解決するように指示され-Xours
ます。これらの人為的なマージ ノードはリベース後に破棄されるため、マージの結果は重要ではありません。
元の参照が失われないように、新しいブランチパックを作成することをお勧めします。上記の例では、次のコマンドが実行されます。
$ git checkout -b pack WIP1 # create new branch at 'WIP1'
$ git merge -s recursive -Xours WIP2 # merges WIP2 into pack (node p2)
$ git merge -s recursive -Xours WIP3 # merges WIP3 into pack
以下は、ツリーがどうなるかを見ることができます。マージにより、 2 つの新しい人工ノード
p2とpackが作成されました。
o (master)
/
/ (WIP1) (p2)
/ o-----o-----o----o (pack)
/ / / /
o--o--o--o-----o-----o / (WIP2)
(X) \ /
o------------o (WIP3)
いよいよリベースです。すべてのブランチ ( pack ) に共通のエンドポイントがあるため、サブツリー全体を簡単に移動できます。
$ git rebase --preserve-merges --onto master X pack
これが生成されます:
(WIP1') (p2')
o-----o-----o----o (pack')
(master) / / /
o----o----o--o--o-----o-----o / (WIP2')
(X) \ /
o------------o (WIP3')
ここで、参照を再配置します。理由はわかりませんが、参照が移動される場合と移動されない場合があります。WIP1、WIP2、WIP3、または必要なものごとに、次のように入力します。
$ git checkout WIP1
$ git reset --hard <WIP1' hash>
最後に、共通のサブツリー エンド ノードを生成するために作成された人為的なコミットを取り除きます。
$ git branch -D pack
$ git branch -D p2 # if there is any
したがって、最終的なツリーは次のようになります。
(WIP1')
o-----o
(master) /
o----o----o--o--o-----o-----o (WIP2')
(X) \
o------------o (WIP3')