I recently started using Mercurial and like the way I have VCS protection for my individual development without checking it in to the central repository, then I push to the central repo when I have something ready for the rest of the team.
When I “hg commit” I write a commit message relevant to the addition since the last time I committed. I may have 5 or so local commits before I’m ready to push stuff to central. When I do push, if I don’t specify a revision, all of my local commits and their messages get added to the central repository, but I don’t want to clutter the central log with all my local smalls steps. When I push and specify the local revision, I think only that revision and its commit message get pushed, right?
The problem is, I want to push with a commit message that summarizes all of my local “offline” work, because that’s what I’m really adding. However, the commit message that gets pushed is whatever I most recently wrote. Say I’m working on feature A and I have five local commits for it; “Added A.1” “Added A.2” “Cleaned up code in foo.cpp” and so on, ending with “Added A.4.” What I want to log to the central repository is “Added A, cleaned up foo.cpp” but if I push that last revision it just sees “Added A.4.” Now, when there have been updates to central I need to merge in locally before I push, my local commit message is “Merged in tip”. Clearly that’s not a good commit message to push back.
What’s a good practice here? I’m not aware of any mechanism to change an existing commit message, or to push with a new commit message. I don’t want to make a trivial change to my local repo simply to enter a new commit message before changing; that’s just silly. I must be missing something because this seems basic. Or am I not thinking about mercurial the right way?
Pushing five changesets is perfectly acceptable and it will make it easier for others to review the code. Just try to make logically consistent changesets; I usually try to ensure that the code compiles and passes tests after each commit.
There are some extensions (collapse, rebase, histedit, mq) that allow you to alter changesets after the fact. The collapse extension is what you want here: it allows you to collapse (combine) your five local changesets into a single changeset that you can then push to the server.
It is important to realize that they do so by creating new changesets and throwing the old ones away. This has the consequence that you should only use them on private changesets, i.e., changesets that has not yet been shared with anybody else.
If you by accident manage to alter a changeset that has already been pushed to your central repository then it’s no catastrophy — what happens is that you will end up with both the original changeset plus the altered changeset. This is because
hg pushis append-only and so you cannot alter a changeset that has been pushed to a central repository.