If you have a bad commit and just want to forget it ever happened, and that commit has no descendants, you can just do hg strip
to remove it from history entirely (requires strip extension).
If the commit does have descendants, you can use hg histedit
(requires histedit extension) to drop the changesets you don't want to keep.
Both these solutions involve editing history, which is risky if you've distributed the bad commit publicly. You will have to coordinate with everyone who may have pulled the bad commit or any of its descendants, which isn't always possible (e.g. in an open source environment). You will also need to redo these changes server-side, since Mercurial's push --force
is not like Git's push --force
.
If you don't want to edit history, you can graft the descendants of the bad commit onto the last known good ancestor (e.g. hg up good_ancestor; hg graft 'bad_commit:: - bad_commit'
), then do hg commit --close-branch
at the bad head(s). Be sure to leave an informative commit message on the close-branch commit, so that other developers will know where to rebase anything that descends from the bad commit.