2016-06-23 8 views
2

gitでのマージをリベースする最も簡単な方法は何ですか?git rebaseを使ってマージの周りにコミットする方法は?

私の枝のうちの1つでは、私はたくさんの失敗した試みと部分的に失敗した試みの両方で、さまざまなものを投機的に遊んでいました。作業が完了したら、インタラクティブなリベースを使用して、推測と確認のコミットを集めて戻したいと思います。

複雑なことは、プロセス中に別のブランチでマージされたことです。私はそのマージされたブランチをそのままにしておきたい(コミットを書き直さずに)、ブランチの同じ場所にマージコミットしておきたい。 (私のブランチの機能には前後関係があるため)git rebase -iを真っ直ぐに実行しようとしましたが、私がマージしたブランチには、最後に分岐したポイントからかなりの数のコミットがあります。インタラクティブなリベースファイルは、物事を複雑にします。

図が役立つ場合があります。私は今持っているもの:

#-#-#-#-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* My branch 
\     /  
    #-#-#-#-#-#-#-#-#-#-#-#-# The merged branch 

私が欲しいもの:

#-#-#-#-----*-------*-*----*------* My branch 
\     /  
    #-#-#-#-#-#-#-#-#-#-#-#-# The merged branch 

(「#」は、私は同じよう維持したいコミット、SHA1ワイズ、および2つのマージコミットのファイルシステムの内容です)

リモートサーバーにリベースしたいコミットのどれもプッシュしませんでした。 (私はをマージブランチは、リモートサーバー上のですが。)

+0

[こちら](http://apasca.blogspot.sg/2012/02/git-rebasing-merge-commits.html)をご覧ください。履歴のマージコミットを手動でやり直さなければならないかもしれません。 –

答えて

3

DavidN's answerが正しいことを覚えておいてください。リベースはです。のコミットをコピーしますが、実行するのは少し難しいです。 2つの特定のコミットIDを保存し、別のブランチ名を使用する必要があります。

私は実際に新しいブランチ名git cherry-pickと新しいgit mergeを使ってこれを行います。あなたのダイアグラムを使用して、わずかに注釈を付けた方法と実際のGitコマンドを使用する方法があります。あなたは持っている:

A-#-#-B-*-*-*-*-*-*-C-M-D-*-*-*-*-*-*-E My branch 
\     /  
    #-#-#-#-#-#-#-#-#-#-#-#-# The merged branch 

は、あなたがしたい:あなたのコミットを指し示す新しいブランチ名を取得します

git checkout -b rebased B 

A-#-#-B-----*-------*-m----*------* My branch 
\     /  
    #-#-#-#-#-#-#-#-#-#-#-#-# The merged branch 

あなたが始めることができますB。今、次のことができます。

git cherry-pick -n B..C 

(または生のIDを使用)を通って、C、その後、git rebase -i Bを含めて最大B後にすべての*コミットをコピーして2つの*コミットを取得するには、いくつかのスカッシュします。

これで、マージの準備が整いました。そのため、git merge M^2Mのsecond-parentとのマージをThe merged branchから行います。それが失敗した場合(または変更したい場合は--no-commitを追加して停止したところです)、マージを解決するには、コミットMからファイルを直接チェックしてください。

(あなたはgit rerereを持っている場合は、こののほとんどは、この時点では、ほとんど自動的に行われ、有効。)

をコミット、またはマージが完了したら、あなたは新しいマージのIDがmをコミットしています。

今、あなたはチェリーピックへの準備が整いましたので、DEを通じて包括的にコミット:

git cherry-pick D^..E 

(私たちはDが含まれ、または取得するためにあなたがコミットの生のSHA-1 IDを使用することができ、ここでD^が必要M、元のマージ)。次にgit rebase -i mを実行して、新しいマージmをバックアップせずに、新しいコピーD-through-Eをリベースします。

すべて完了したら、必要な図があります。ブランチの名前はMy branch,ではなくrebasedですが、コミットEを指すブランチMy branchがあります。従ってgit checkout My branchそしてgit reset --hard rebasedは新しいブランチチップコミット時に古い名前を指し示し、その後に名前rebasedを削除することができます。


支店名にスペースを持つことは悪いですので、これは明らかに、実際の名前ではありません。

+0

あなたは実際に説明全体を書く時間がかかりましたので、あなたのために1つを足してください。 – DavidN

+0

--ontoオプションを使用する代わりにcherry-pickを使用する特別な理由はありますか? –

+0

この特殊なケースの方が簡単です。コミットの2つのセットをコピーし、その中に1つのマージをコピーする必要があります。 'git rebase -i -p'はおそらく正しいことですが、ドキュメンテーションでは、シーケンスにマージがあるときにコミットリストを編集することにそれが嫌な(rebase -p')と警告しています。 – torek

2

あなたは、マニュアル的なアプローチを取り、ちょうど自分のものを下に潰すためにTheMergedBranchするMyBranchからコミット最初の分岐の間MyBranch上でインタラクティブなリベースを行うことができます。 TheMergedBranchでマージします。それから、インタラクティブなリベースを行います。アップストリームで新しいブランチに移り、オリジナルのMyBranchからコミットしてコミットします。

0

これにリベースを使用しないでください。グラフトを使用してください。コミットはフル・コンテンツ・スナップショットであり、結果として既存のコミットと内容が同じで、親子を再配線したいだけのコミットを覚えておいてください。それは移植片のためのものです。

まず、あなたは何が起こっているか気に入らない場合、あなたはそれを放棄して拭くことができるようにサンドボックスのレポで次の操作を行います。

(あなたが

echo > .git/info/grafts $(git rev-parse M B M^2) 
echo >>.git/info/grafts $(git rev-parse E M) 

を望む親子関係を設定

git clone -s . "${other=`mktemp -dt`}" 
cd "$other" 

私はあなたがそこにほしい1つまたは2つ以上のコミットを持っていると思うだけで、あなたが持っているものの代わりに本当に親のために望むコミットを列挙すれば、gitのリビジョンウォーキングはあなたのリードに続くでしょう)

その後

git filter-branch -- --all 

結果が好きな場合は、戻します。

+0

グラフト?私は移植について聞いたことがありません - あなたは良い説明へのリンクを持っていますか? –

+0

グラフトは、レポローカルの祖先オーバーライドです。 gitの中で、祖先が移植された祖先を見るものは何か、特にコミットを書き直すものはそれを見るので、書き直したコミットに焼き付けます。それ以外には何もありません。あなたはレポの履歴が現在とは異なる祖先構造を持つことを希望するときはいつでもそれらを使用します。 – jthill

関連する問題