21

次のリビジョン グラフがあるとします。

A-X-Z--B
     \
      \-C

A は B と C の両方に先行します。さらに、上流から A をリベースし、新しいコミット A* を作成してから、B と C の両方を A* にリベースするとします。結果のリビジョン グラフは次のとおりです。

A*-X'-Z'-B
 \
  \-X"-Z"-C

共有履歴は共有されなくなったことに注意してください。たとえば、B をリベースしてから C を明示的に Z' にリベースする以外に、これを修正する簡単な方法はありますか。つまり、共有履歴を保持するために、複数のブランチを同時に自動的にリベースするより良い方法はありますか? スプリットポイントに人為的にタグを配置するか、グラフを手動で調べて、共有履歴を保持するためにCをリベースするコミットのsha1を見つけなければならないのは、少し厄介に思えます。可能性を開くことは言うまでもありません特に、変更を上流ブランチにチェックインするまで、リベースするたびにこれを行う必要があるためです。

4

2 に答える 2

18
git rebase --committer-date-is-author-date --preserve-merges --onto A* A C
git rebase --committer-date-is-author-date --preserve-merges --onto A* A B

これにより、共通のコミットで同じ sha1 が保持され、マージが保持されます。この場合、マージの保持は必要ありませんが、それほど重要ではない歴史を持つ問題になります。

履歴に A を含むすべてのブランチに対してこれを行うには、次のようにします。

git branch --contains A | xargs -n 1 git rebase --committer-date-is-author-date --preserve-merges --onto A* A 

お役に立てれば。

アップデート:

これはよりクリーンな構文かもしれません:

for branch in $(git branch --contains A); do git rebase --committer-date-is-author-date --preserve-merges --onto A* A $branch; done
于 2011-04-12T06:53:06.080 に答える
2

一般的な場合の問題

私は同様の問題に関心を持っていました: サブヒストリー全体のリベース - いくつかのブランチと、それらの間のいくつかのリンクがマージの結果です:

A--B-B2-B3 <--topicB
\   /
 \-C-C2-C3 <--topicC

git rebase(topicB と topicC に対して)いくつかを連続して実行すると、ブランチ間のマージが正しく保持されるとは思えません。したがって、すべてのブランチを一度にリベースする必要があり、それらの間のマージが正しく再構築されることを期待しています。

特定のサブケースで機能した「ソリューション」

私の場合、topicC実際にマージされた運がありましたtopicB

A-B-----------B2-B3 <--topicB
   \         /
    \-C-C2-C3 <--topicC

サブヒストリー全体をリベースするには、実行するだけです

git rebase -p A topicB --onto A*

(は、質問のようにA*ではなく、新しいベースです。は、最初は古いコミット B3 を指し、後で書き換えられたコミットを指すブランチ名です。は、オプションの短い名前です)、次のような履歴を取得します。AtopicBB3'-p--preserve-merges

A-B-----------B2-B3
   \         /
    \-C-C2-C3 <--topicC

A*-B'-------------B2'-B3' <--topicB
    \            /
     \-C'-C2'-C3'

次に、残りのすべてのブランチ ref (およびタグ) を新しい対応するコミット (新しいサブヒストリー内) にリセットします。

git branch -f topicC C3'

出来た:

A*-B'-------------B2'-B3' <--topicB
    \            /
     \-C'-C2'-C3' <--topicC

(ブランチ ref とタグの移動は、おそらくscriptで行うことができます。)

その特定のケースに触発された一般的なケースの「ソリューション」

topicCにマージされていない場合はtopicB、偽のトップ コミットを作成して、リベースしたいすべてのブランチをマージできます。

git checkout -b fake topicB
git merge -s ours topicC

そして、そのようにリベースします:

git rebase -p A fake --onto A*

トピックブランチを新しいコミットにリセットし、偽のブランチを削除します。

その他の回答

他の回答も適切で賢明だと思いますが、Gitでの私--committer-date-is-author-dateの経験では、その考えがなく、追加の回答で説明した方法で、リベース後に共有履歴を実際に共有し続けるという問題を解決しましたここ。

于 2012-03-14T17:00:01.213 に答える