Mercurial - backout an old merge

前端 未结 6 1642
礼貌的吻别
礼貌的吻别 2021-02-13 02:24

I have a branch that looks like this:

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

where C is a merge from 2 an

6条回答
  •  北恋
    北恋 (楼主)
    2021-02-13 02:59

    Merge is public and there are public commits on this merge

    Assume we have this published history of commits (top is the newest):

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

    Instead, we would like to have top state as if we had this history:

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

    How to achive this (step by step)

    1. Callapse the history after merge commit (revD - revZ) into one commit

      $ 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. Copy changes after merge (revTmp1) to wanted branch (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. Create a "backout" commit

      $ 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. Clean the temporary commits

      $ hg strip revTmp1 revTmp2
      
                        revZ'          <- reverted revC merge
                         |  
                        revZ
                         |  
                        revD
                         |
                        revC     <- unwated merge commit (rev2 to revB)
                         |   \    
      wanted branch ->  revB  rev2    <- unwanted branch
                         |     |
      

提交回复
热议问题