Collapse extension for Mercurial
The collapse extension adds a new command, 'collapse', to Mercurial. This collapses a number of committed changesets into a single changeset. If the last collapsed changeset is not a head, the sequence of changesets that follow it are rebased onto the collapsed one.
So for example:
Before: 1 --> 2 --> 3 --> 4 $ hg collapse -r 2:4 After: 1 --> 2[2-4] Before: 1 --> 2 --> 3 --> 4 $ hg collapse -r 2:3 After: 1 --> 2[2-3] --> 3[was 4] Before: 1 --> 2 --> 3 --> 5 --> 6 \--> 4 ---/ $ hg collapse -r 2:5 After: 1 --> 2[2,3,4,5] --> 3[was 6]
The collapse command will concatenate the commit messages of the original revisions to form the message for the collapsed one, and will invoke your editor to edit it before committing the collapsed revision.
I've thrown this together fairly quickly using a very scant understanding of the Mercurial code base. It has not received much testing to date. Therefore it should be used with extreme caution. I would strongly recommend creating a backup clone of your repository before using it.
I would be very grateful for any feedback in the form of defect reports, enhancement suggestions or code reviews.
Simply copy the collapse.py file to a location on your computer or network, then add the following to your mercurial.ini or .hgrc file:
[extensions] hgext.collapse = /path/to/collapse.py
$ hg help collapse
to make sure it has been enabled.
This extension is particularly useful when you follow the practice of committing regularly to your local repository, possibly before you've got anything sufficiently complete to be put in a shared repository. Rather than filling the changelog with changes of the "OK it almost works now" type, you can collapse all of your intermediate commits before pushing to the shared repository.
N.B. 'hg collapse' is destructive; it rewrites history. Therefore you should never collapse any changeset that has been pushed to another repository, unless you really know what you are doing.
When you can't collapse
I've imposed some rules about what you can collapse and what you can't. You can't collapse if:
- Any of the revisions to be collapsed other than the last one have child revisions outside of the collapse group. E.g.
1 --> 2 --> 3 --> 4 \--> 5 $ hg collapse -r 2:4
(In this case you could resolve the issue by using the rebase extension to rebase 5 on 4, and then collapse 2-4.)
- Any of the revisions to be collapsed other than the first one have parent revisions outside of the collapse group. E.g.
1 --> 2 --> 4 --> 5 3 ---/ $ hg collapse 2:5
- The first revision in the collapse group has multiple parents. E.g.
1 --> 2 --> 4 --> 5 3 ---/ $ hg collapse 4:5
(The rationale for disallowing this is that it is good practice for a merge revision to contain only the merge; additional work should be in a separate commit. It might be an idea to allow this rule to be overridden using the -f option at some point though.)