16

次のようなブランチがあります。

A->B->C->D->...->Z
     ^
1->2-^

Cマージ元2とその祖先はどこにありますか。

合併しなくてよかったと今になって思いました。戻ってB移植することもできDますZが、それは大変な作業です。JUST をバックアウトできますCか?

しようとするhg backout --merge Cと、abort: cannot backout a merge changeset が表示されます。

これらの変更は中央レポにプッシュされました。履歴などを変更するつもりはありません。逆にしたいだけで、2その先祖を共通の子孫に戻したいだけですB

4

6 に答える 6

13

マージは公開されており、このマージには公開コミットがあります

この公開されたコミットの履歴があるとします (上が最新です)。

                  revZ
                   |
                  ...  
                   |
                  revD
                   |
                  revC     <- unwated merge commit (rev2 to revB)
                   |   \    
wanted branch ->  revB  rev2    <- unwanted branch
                   |     |

代わりに、この履歴があるかのようにトップ状態を保持したいと考えています。

                  revZ'
                   |
                  ...  
                   |
                  revD'
                   |       
wanted branch ->  revB  rev2    <- unwanted branch
                   |     |

これを達成する方法(ステップバイステップ)

  1. マージ コミット (revD - revZ) 後の履歴を 1 つのコミットにまとめる

    $ hg update -r revC                # Update to merge commit
    $ hg revert --all -r revZ          # revert to the newest commit
    $ hg commit -m "collapsed commits" # Create new commit (revTmp1)
    
                       revZ
                        |  
                       ...
                        |  
               revTmp1 revD
                     \ /
                     revC
                      |  \    
                    revB  rev2
                      |    |
    
  2. マージ後の変更 (revTmp1) を必要なブランチ (revB) にコピーします

    $ hg update -r revB    # Update to the last "wanted" commit before merge
    $ hg graft -r revTmp1  # Copy changes from revTmp1 (create revTmp2 commit)
    
                       revZ
                        |  
                       ...
                        |  
               revTmp1 revD
                     \ /
            revTmp2  revC
                  \  / \    
                 revB  rev2
                   |     |
    
  3. 「バックアウト」コミットを作成する

    $ hg update -r revZ                   # Update to the top commit
    $ hg revert --all -r revTmp2          # Copy state revTmp2
    $ hg commit -m "reverted revC merge"  # Create revZ' commit
    
                       revZ'
                        |
                       revZ
                        |  
                       ...
                        |  
               revTmp1 revD
                     \ /
            revTmp2  revC
                  \  / \    
                  revB  rev2
                   |     |
    
  4. 一時コミットを消去する

    $ hg strip revTmp1 revTmp2
    
                      revZ'          <- reverted revC merge
                       |  
                      revZ
                       |  
                      revD
                       |
                      revC     <- unwated merge commit (rev2 to revB)
                       |   \    
    wanted branch ->  revB  rev2    <- unwanted branch
                       |     |
    
于 2016-10-19T22:18:36.333 に答える
10

少し遅れましたが、私は少し前に同じ状況にありました。これは私にとってスムーズに機能しました:

hg update -C -r "revision-C"
hg revert --all -r "revision-B"
hg commit -m 'UNDO blah blah whatever the merge did'
hg update -C -r "revision-Z-or-whatever-the-current-head-is"
hg merge -r "the-new-revision-created-in-step-3"

基本的に、これはまさにバックアウトが行うことです。

免責事項:ただし、後で 1->2 ブランチを再度マージする場合は、おそらくいくつかの問題が発生する可能性があることに注意してください。そして、「いくつかの問題」は、ここではやや婉曲的な用語です。実際、そのような場合、大きな問題が発生することさえあります。このシナリオは、主に問題がかなり後で発生し、まったく予期しない可能性があるため、危険です。これらのリスクを回避するために、「1」ブランチを完全に放棄することを強くお勧めします。(以下のコメントも参照してください。)

詳細については、バックアウト wiki ページを参照してください。

于 2013-11-26T09:47:13.720 に答える
2

バックアウト ツールを使用しますが、何をしているのかに注意してください。

  1. マージ変更セットへの更新 (C)
  2. その変更セットを右クリック -> [バックアウト] をクリックします
    • ブランチでバックアウトした後、すぐにコミットする必要はありません。(オプションを選択した後に発生した変更の中にBackout)元に戻したくない他のブランチからの変更がないかどうかを事前に確認することをお勧めします。その場合は、コミットする前にチェックを外してください。
  3. コミットをクリックします
    • 1-2ブランチ(または「番号付きブランチ」)を今(またはそれ以降)ブランチにマージすると、変更セット(含む)のA-Z前に「番号付きブランチ」からのすべての変更が失われます2-それが@Marvinの回答の警告です。
    • これを回避するには、このバックアウトを「番号付きブランチ」に伝播し、バックアウトされた変更をやり直す必要があります (後の手順)。
  4. ブランチA-Zが「番号付きブランチ」の直接の祖先でない場合は、最初の子孫ブランチを と の間A-Zで見つけ、1-2ワークベンチをその先端に更新します。
  5. A-Z(= backout)の最新リビジョンを右クリック-> Merge with local をクリックします
    • A-Zとの間にさらに分岐がある場合は1-2、手順 4. と 5. を繰り返します。
    • まだ何もブランチにマージしないでください1-2
    • 注: ブランチは、元のブランチにのみマージしてください。そうしないと、将来のマージ後に一部の変更が失われる危険があります。
  6. 「番号付き枝」の先端に更新。
  7. バックアウトによって変更された (ファイルシステム上の) すべてのファイルを見つけて、一時ディレクトリにコピーします。
  8. 番号付きブランチの先祖の最新リビジョンを右クリック -> Merge with local をクリック
  9. 手順 7 のファイルをファイル システムにコピーします。
  10. worbench の変更を確認し、ブランチからではないすべての変更のチェックを外します1-2(たとえば、リビジョンからの変更D- Z)。
    • 残念ながら、これは手動で確認する必要があります。しかし、これが両方の分岐を修正する唯一の安全な方法です。
  11. コミットをクリック

ヒント:マージによってどのファイルが影響を受けたかを確認するには、そのリビジョンを右クリックし、[親との差分] をクリックします。

これは基本的に、1 つのブランチ (まだ開発中) が誤ってデフォルトにマージされたことがわかったときに、今日使用したシナリオです (リビジョン グラフで同じ色の別のブランチではなく :)。(両方のブランチは、このマージ後に変更をプッシュしました。) 時間がかかるように思えるかもしれませんが、マージをバックアウトして数日 (または数週間) 後に多数の予期しないエラーを見つけるよりはましです。(私自身の経験です。)

于 2016-08-12T16:42:35.540 に答える
1

DにリベースできZますB。rebaseのドキュメントでは、同様の状況についても説明しています。これは 1 つのコマンドで実行できるはずです。

于 2013-08-09T14:40:32.757 に答える
1

thg backout ツールを使用できます。

  1. マージ変更セットへの更新 (C)
  2. バックアウト
  3. バックアウトする親を選択してください ((2) のリビジョンが何であれ) -実際にはダイアログで、保持したい変更をバックアウトしない親を選択することに注意してください
  4. [次へ] をクリックします
  5. コミットをクリックします

これにより、Z とマージするか、Z にリベースする必要がある新しい頭が作成されます。

于 2013-08-09T13:12:36.217 に答える