I have a branch that looks like this:
A->B->C->D->...->Z
^
1->2-^
where C
is a merge from 2
an
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
| |
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
| |
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
| |
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
| |
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
| |