2
votes

I'm trying to grasp the Mercurial basics so please bear with me. :) My current workflow is as follows:

  • do some work until I'm ready to commit or need the others' changes
  • pull
  • at this point I'd like to merge my work with the latest changesets and commit, however Mercurial insists on me committing before merging
  • so it goes like "commit, merge, commit" and I'm basically committing everything twice, writing the same notes in both changesets and pushing two changesets at a time

Is it intended to be so? Is it possible to have just one changeset coming from me with every merge? Is it indeed desirable?

I've read a lot of online manuals but still feel I do not have solid understanding of the process. All comments are welcome. Thanks!

EDIT: Turns out I didn't know that update could merge incoming changes with uncommitted edits.

3
There's another thread hereabouts that might help answer your questions.smooth reggae
You should just pull a little less often :), just once or a couple of times a day ought to be enough. There’s usually no need to pull after every commit, especially if you keep your commits small.Laurens Holst

3 Answers

3
votes

Merging always creates a separate changeset in Mercurial.

Plus, merging is not possible as long as you have uncommitted stuff in your local repository.
So the solution is to commit first, and pull and merge afterwards.
This will always result in two changesets, not one.
(...because merging always creates a separate changeset)

But you don't commit the same stuff twice, and especially you shouldn't write the same commit message twice:

The first commit is what you actually changed ("fixed a bug in the foo bar").
The second commit is just the merge (TortoiseHG actually pre-populates the commit message with "Merge", 99% of the time I just leave it like that).

2
votes

This workflow will prevent a merge in the history, but you still do a merge as noted below:

  • Do some work until you are ready to commit or need another's changes.
  • hg pull
  • hg update (Note: hg pull -u does this and the previous in one step.

During hg update, your uncommitted changes will be merged with the new tip of your current branch. You will still have to resolve any conflicts.

  • hg commit when ready.

I still recommend if you have extensive changes to commit first before pulling/merging because it is easier to start over by updating to that changeset if the merge goes badly.

Keeping the hg pull and hg update separate allows you to look at the incoming changesets and predict how the merge will go.

1
votes

The reason is feels strange is that you delay your commit until you want to integrate with the others.

A big feature of distributed version control is that commits are local. Because they're local you should commit often — commit every time you have a small consistent chunk of work done. Your commits are not inflicted on others immediately so you wont interrupt them by making many small commits.

If you begin making more commits you'll see that your workflow becomes:

$ hg commit -m "Refactoring for Issue123"
$ hg commit -m "Basic functionality for Issue123"
$ hg commit -m "Fixed off-by-one error (Issue123)"
$ hg commit -m "Finished implementing Issue123"
$ hg commit -m "Added more tests for Issue123"
$ hg commit -m "Begin use new function from Issue123"
$ hg pull
$ hg merge
$ hg commit -m "Merge"

Here the ratio of merge commits to "real" commits is much more sensible.

Many people (myself included) like to use the rebase extension to avoid the merge completely. That extension linearizes the commits by faking the history so that it looks like you did your four commits after the changesets you pulled down with hg pull. The only change in workflow is that you hg rebase instead of hg merge above and then skip the final commit.