Ability to unmerge or revert a merge sensibly
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Bazaar |
Confirmed
|
Wishlist
|
Unassigned |
Bug Description
This is a pretty important use case for Twisted, for example. We occasionally (enough that a very strange workflow would get really annoying) have situations where a branch has been reviewed and merged but we later decide needs to be reverted. The workflow for this situation is very bad, because if you revert the change (with a "bzr merge -r branchrev.
Right now the workaround is to do a series of arcane hacks to get the branch back into a working state, and AFAICT it leaves the branch in a state where history is lost or at least dissociated.
From what I hear the proper implementation a better system would be dependent on "cherry picking" support. I don't know anything about this, but here are a couple ideas for a UI:
1. Just what I did above, with a revert of the merge revision, except without having to "fix" the reverted branch so it can later be merged. Would cherry picking support automatically make this work?
2. Add a "bzr unmerge <other-branch>" command which reverts all changes from <other-branch> that were made to the current branch, and does whatever necessary to make it so <other-branch> is still mergable later.
Changed in bzr: | |
status: | Triaged → Confirmed |
tags: | added: check-for-breezy |
At the moment, this isn't representable in our data model. The problem is that history is immutable, and you have a revision which says it includes everything from the other branch.
In our current model, if "X" is in your history, than all ancestors of "X" are also included. This is vastly simplifies the work you have to do to find common ancestors between two branches. (Without it, you always have to search all of history to see if one of the ancestors was selectively not merged).
To further clarify, you aren't trying to unmerge the last commit, but instead one several commits ago, correct? The only way to do that (at the moment) is to uncommit back to just before the merge, and then recreate all the other commits (skipping the merge one). Which is something Jelmer's "rebase" plugin should be able to help with.
Or you could do something like:
cd existing
bzr branch -r -10 ../before_merge
cd ../before_merge
bzr merge -r -10..-1 ../existing # This "skips over" the merge revision, and cherry picks the rest
bzr commit -m "Cherry pick the changes since the merge"
cd ../existing
bzr pull --overwrite ../before_merge
This will lose the identities of the individual commits since the point you want to extract. Which is where "rebase" would actually try to merge and commit them one by one. So they would have new identities, but the textual changes and commit messages should be preserved.
You are actually looking for more of a "cherry-unpick" function (than a "cherry-pick"), and is certainly a use case we need to think carefully about.