tags:

views:

247

answers:

6

Subversion shop considering switching to Mercurial, trying to figure out in advance what all the complaints from developers are going to be. There's one fairly common use case here that I can't see how to handle.

  1. I'm working on some largish feature, and I have a significant part of the code -- or possibly several significant parts of the code -- in pieces all over the garage floor, totally unsuitable for checkin, maybe not even compiling.
  2. An urgent bugfix request comes in. The fix is nice and local and doesn't touch any of the code I've been working on.
  3. I make the fix in my working copy.

Now what?

I've looked at "Mercurial cherry picking changes for commit" and "best practices in mercurial: branch vs. clone, and partial merges?" and all the suggestions seem to be extensions of varying complexity, from Record and Shelve to Queues.

The fact that there apparently isn't any core functionality for this makes me suspect that in some sense this working style is Doing It Wrong. What would a Mercurial-like solution to this use case look like?

+1  A: 

Lots of useful functionality for Mercurial is provided in the form of extensions -- don't be afraid to use them.

As for your question, record provides what you call partial commits (it allows you to select which hunks of changes you want to commit). On the other hand, shelve allows to temporarily make your working copy clean, while keeping the changes locally. Once you commit the bug fix, you can unshelve the changes and continue working.

The canonical way to go around this (i.e. using only core) would probably be to make a clone (note that local clones are cheap as hardlinks are created instead of copies).

avakar
Not afraid to use extensions, but afraid to use extensions as a way to avoid changing my thinking. I guess I need to find a way to make local clones as cheap for the IDE as they are for the filesystem...
David Moles
+1  A: 

You would clone the repository (i.e. create a bug-fix branch in SVN terms) and do the fix from there.

Alternatively if it really is a quick fix you can use the -I option on commit to explicitly check-in individual files.

Paolo
Good point about -I. Actually, now that I'm looking at the hg man page, instead of just fielding complains from people who've been skimming tutorials, I'm not sure the commit behavior is as different from svn as I thought.
David Moles
The `-I` option is not even needed, you can just do `hg commit foo.c bar.h`. I see the `-I` and `-X` options as something you use if you want to do fancy include/exclude filters. I personally never use them since my shell can do the required globbing for me.
Martin Geisler
+2  A: 

Like any DVCS, branching is your friend. Branching a repository multiple ways is the bread and butter of these system. Here's a git model you might consider adopting that works quite well with Mercurial, also.

Santa
Yeah, I had a feeling that would be the answer. Might have to wait for IDEs to catch up to the idea of rapid switching between branches.
David Moles
+1  A: 

Here's how I would handle the case:

  1. have a dev branch
  2. have feature branches
  3. have a personal branch
  4. have a stable branch.

In your scenario, I would be committing frequently to my branch off the feature branch.

When the request came in, I would hg up -r XYZ where XYZ is the rev number that they are running, then branch a new feature branch off of that(or up branchname, whatever).

Perform work, then merge into the stable branch after the work is tested.

Switch back to my work and merge up from the top feature branch commit node, thus integrating the two streams of effort.

Paul Nathan
That makes sense.
David Moles
+1  A: 

In addition to what Santa said about branching being your friend...

Small-granularity commits are your friend. Rather than making lots of code changes in a single commit, make each logically self-contained code change in its own commit. Then it will be a lot easier to cherry-pick changes to merge between branches.

Craig McQueen
+1  A: 

Don't use Mercurial without using the Mq Extension (it comes pre-packaged in the default installation). In addition to solving your specific problem, it solves a lot of other general problems and really should be the default way that you work (especially if you're using an IDE that doesn't integrate directly with Hg, making switching branches on the fly a difficult way to work).

Nick Bastin