2013-01-08 6 views
8

私はちょうど--strategy=oursフラグ(--strategy-option = oursフラグを使用していた)を使用していたため、HEADに何も変更を加えていないことを発見した数週間前にマージされたリポジトリを使用しています。しかし、変更を適用する必要があります。 Gitはすでにブランチがマージされていることとブランチの履歴にコミットしていることを認識しています。strategy = oursを使ったマージを元に戻すには?

マージのこの種のは、元に戻すおよび/またはファイルを変更するには、マージを再適用する適切な方法だろう何git revert -m ...

を使用して元に戻すことはできませんか?

master A - B - E - F - G ---> L - M - N 
      \ /
topic   C - D 

このシナリオでは、マージコミット(F)が原因です。

+0

はただのファイルにマージする枝の先端に新しいコミットを作る、あなたは歴史を書き換えたくないと言って、それは安全ですか? –

+0

実際には、履歴の書き換えはまともな選択肢になります。このような状況では、変更が実際に適用されている限り重要ではありません。何かに注意してください:私たちはブランチ 'マスター'へのマージを修正しようとしています。マスターは何十回も分岐していますので、履歴は他のブランチにマージすることができるはずです。 –

答えて

6

この問題の解決策を発見しました。 Linusが手紙の中に誤りの合併を復活させることについて書きました:How to revert a faulty merge。 このケースのgit merge --strategy=ours topicは意図されていませんでした。マージに誤りがあっても、元に戻すことはできません。また、長い間押されていても、リバートコミットを元に戻すことはできません。

解決策は、トピックブランチをチェックアウトし、最初のコミットからrebase --no-ffを実行してから、そのブランチをマスターに戻してマージします。

fixed–topic C'–––D'––––––––––––––––––––- 
      /       \ 
master A–––B–––E–––F–––G –––> L–––M–––N–––F2 
      \ /
topic   C–––D 

は本当に、で徹底的にこれを理解してブランチを再作成する--no-ffリベースのオプションを使用して文字How to Revert a Faulty Mergeの最後の部分を読むために:

git checkout topic 
git rebase -i --no-ff <C> 
git checkout master 
git merge topic 

この

は降伏の効果がありました。

0

「マージしているものが何であっても、ここに何を残しておくのか」というマージ戦略は、その性質上、元に戻すことはできません。新しいブランチでマージの最初の親をチェックアウトしてから、再度マージします。 Rebase - 元のマージを上に置いた残りのコミットをこの上にマージします。

UPDATE:あなたは過去を気にしない場合は、あなたの場合は

、あなたはE上にG-Nをリベースしてからちょうどこの新しいマスターにDをマージすることができます。リベースは、Fが〜のマージであったので簡単です。

+0

ところで、私は私の質問を少し鮮明に編集しました。 - このマージが実行されてから、マスターブランチに対して69回のコミットが行われました。私はチームのメンバーのリポジトリに潜在的に壊滅的な失敗を引き起こし、リベースのマージを再び私のレポジスにマージすると、面白くなる可能性があるこのケースの履歴を書き直すことに懸念しています。おそらく、まともな選択肢がない場合、パッチルートに行くのが最も安全な方法でしょうか? –

+0

リベースとパッチは最後に同じものです。しかし、リベースははるかに自動化されています。再起動が必要な場合や、同じ競合解決を再度実行したくない場合に備えて、あなたのrerereをオンにすることを忘れないでください。 –

3

@Highway of Lifeは素晴らしい答えがあります。 1つは、リベースされたコミットが新しい異なるコミットのように見えることです。多くの場合、これは望ましくない可能性があります。私は同じコミットをもう一度マージしようとしましたが、git-mergeはこれを防ぎます。しかし、私はあなたが望むことを行うためにgitを得ることが常に可能であることを何度も見つけます。

  1. 生活者の指示の

    フォローハイウェイが、マスター上にまっすぐにマージされません。

    git checkout -b fixed-topic <D> 
    git rebase -i --no-ff <B> 
    git checkout -b re-merged master 
    git merge fixed-topic 
    

    これは、その結果:

    今ツリーは、あなたがしたい正確にどのように設定されている
    re-merged    ––––––––––––––––––––------R 
            /      /
    fixed–topic  C'–––D'      /
           /       /
    master  A–––B–––E–––F–––G –––> L–––M–––N–––F2 
           \ /
    topic   C–––D 
    
  2. - ファイルには、あなたが望む内容が正確に表示されます。 1つの問題は、マージコミットの親が実際に元のコミットではなく元のコミットのリベースされたコピーであることです。それはgit-reparentでこの問題を解決するのは簡単です:

    git reparent -p master -p <D> 
    

    これはで終わる:注意すべき重要なことは、Rの内容は、最後のステップのみの両親以降に変更されていないということです

    master  A–––B–––E–––F–––G –––> L–––M–––N–––F2 
           \ /      \ 
    topic   C–––D       \ 
             \       \ 
    re-merged    ---------------------------R 
    

    。新しいマージへ

  3. 早送りマスターがコミット:

    git checkout master 
    git merge re-merged 
    
  4. 最後にあなたが

    git branch -d fixed-topic re-master 
    

完了してクリーンアップすることができます!今、あなたの歴史は、一方の枝で、次のようになり二回合併:

master A–––B–––E–––F–––G –––> L–––M–––N–––F2---R 
      \ /      /
topic   C–––D---------------------------- 
+0

'reparent'オプションが第三者の関数であることはわかりませんでした。シームは非常に良い解決策ですが、私はよりシンプルなものを探していました。 –

関連する問題