I am trying to clean up some local (draft) mercurial history before I push to our master repository. One step that I'd like to take is to squash / roll together a "Fixup" changeset into its parent. My history looks like this:
o [draft] 14 X
|
| o [draft] 13 Y
|/
o [draft] 12 Fixup
|
o [draft] 11 Thing to Fix
|
o [draft] 10 Z
|
~
When done, it should look like this:
o [draft] 13 X
|
| o [draft] 12 Y
|/
o [draft] 11 Thing to Fix with Fixup
|
o [draft] 10 Z
|
~
Obviously rolling two commits together shouldn't create any conflicts, since the code of the descendants is untouched. However, I can't find a way to get histedit to allow me to edit that far back in my history, since it needs to edit "A changeset together with all its descendants."
Is this edit possible? How should it be done?
It's certainly possible. I don't know how to do it easily, though.
The trick is to turn this:
o [draft] 14 X
|
| o [draft] 13 Y
|/
o [draft] 12 Fixup
|
o [draft] 11 Thing to Fix
|
o [draft] 10 Z
|
~
into:
o [draft] 16 Fixup
|
o [draft] 15 Thing to Fix
|
| o [draft] 14 X
| |
| | o [draft] 13 Y
| |/
| o [draft] 12 Fixup
| |
| o [draft] 11 Thing to Fix
|/
o [draft] 10 Z
|
~
where 15 is a copy of 11 and 16 is a copy of 12. (Use hg graft
to do this.) You can now use hg histedit
to combine these two.
It's now easy to copy 13 and 14 atop the new 15 that has replaced the old 15-and-16:
o [draft] 17 X
|
| o [draft] 16 Y
|/
o [draft] 15 Thing to Fix with Fixup
|
| o [draft] 14 X
| |
| | o [draft] 13 Y
| |/
| o [draft] 12 Fixup
| |
| o [draft] 11 Thing to Fix
|/
o [draft] 10 Z
|
~
Now you can hg strip -r 11
to remove 11, 12, 13, and 14, leaving only the corrected commits. (Note that you can use rebase to simplify this a bit. The long form is mainly for illustration and ease of comprehension.)