views:

199

answers:

3

I'm a Subversion user, and I think I've got my head mostly around it all now. So of course now we're thinking of switching to Mercurial, and I need to start again.

In our single repository, we have the typical branches, tags, trunk layout. When I want to create a feature branch I:

  • Use the repo browser to copy trunk to branches/Features/[FeatureName].
  • Checkout a new working copy from branches/Features/[FeatureName].
  • Start working on it.
  • Occasionally commit, merge trunk in, resolve conflicts and commit.
  • When complete, one more merge of trunk, then "Reintegrate" the feature branch into trunk.

(Please note this process is simplified as it doesn't take into account release candidate branches etc).

So I have questions about how I'd fulfil the same requirements (i.e. feature branches rather than working on trunk) in Mercurial:

  • In Mercurial, is a branch still within the repository, or is it a whole new local repository?
  • If we each have a copy of the whole repository, does that mean we all have copies of each other's various feature branches (that's a lot of data transfer)?
  • I know Mercurial is a DCVS, but does that mean we push/pull changes from each other directly, rather than via a peer repository on a server?
+7  A: 

In Mercurial, is a branch still within the repository, or is it a whole new local repository?

The equivalent of the subversion way of working would be a repository with multiple heads in mercurial. However, this is not the idiomatic way of doing things. Typically you will have only one head in a given repository, so separate repositories for each branch.

If we each have a copy of the whole repository, does that mean we all have copies of each other's various feature branches (that's a lot of data transfer)?

Yes, if you look at the history of the head of your local repository, then you'll be able to see all the feature branches that were merged in. But mercurial repositories are remarkably space efficient. For example, I have done a hg clone http://selenic.com/repo/hg to get the source for mercurial itself, and it is only 34.3 MB on an NTFS file system (compared to the source code download, which is 1.8 MB). Mercurial will also make use of hardlinks if your file system supports it, so there is little overhead if you clone a repository to another location on the same disk.

I know Mercurial is a DCVS, but does that mean we push/pull changes from each other directly, rather than via a peer repository on a server?

One way of working is indeed to have each developer expose a public repository in which he pushes his own changes. All other developers can then pull what they want.

However, typically you'll have one or more "blessed" repositories where all the changes are integrated. All developers then only need to pull from the blessed repository. Even if you didn't explicitly have such a blessed repository I imagine people would automatically organize themselves like that, e.g. by all pulling from a lead developer.

Wim Coenen
One can adapt decentralized workflows from Bazaar doc: http://doc.bazaar.canonical.com/bzr.1.18/en/user-guide/index.html#decentralized-with-shared-mainline
Marcin Gil
But if it's a separate repo for each branch, and each repo should have only one head, then where do the "feature repositories" go when you want to put them somewhere safe? How do you get the feature changes into the "blessed repo"?
Neil Barnwell
@Neil: a mercurial hosting service such as google code will typically have a way to quickly and easily create new branches, so you can put your experimental changes "somewhere safe".
Wim Coenen
It seems to me that a couple years ago people preferred branch-per-repo (and BOS endorsed it in the red-bean book), but hg's support for working with branches in a repo is a lot better now. Personally I switched from bzr to hg primarily because of hg's support for repos with multiple heads, and I much prefer that approach.
Carl Meyer
+7  A: 

I recommend reading this guide http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial//

teerapap
+1 I especially liked the tip on how to avoid the overhead of cloning each branch repository separately over an Internet connection
Wim Coenen
Definitely a nice guide, but just a link and no direct answers to any of the questions raised. +0
Daniel
+4  A: 

Steve Losh's article on branching in mercurial linked above is fantastic. I also got into some explaining of branching and how the DAG works in a presentation I gave a couple of months ago on mercurial that's out on slideshare. The pertinent slides start at slide #43.

I think that understanding that all commits to the same repository are stored in a DAG (Directed Acyclic Graph) with some simple rules really helps demystify what's going on.

  • a node with no child nodes is a "head"
  • the root node has no parents
  • regular nodes have a single parent
  • nodes that are the result of a merge have two parents
  • if a merge node's parents are from different branches, the child node's branch is inherited from the first parent

Named branches are really just metadata labels on commits, but really aren't any different than the anonymous branches that happen when you merge someone elses work into your repository, or if you go back to an earlier version and then make a commit there to make a new head (which you can later merge).

Ted Naleid
+1 thanks for sharing your slides. The only thing I think is missing is a mention of `hg transplant`. Most of my svn merges are back-ports of bug-fixes to maintenance branches, and such merges aren't really equivalent to `hg merge`.
Wim Coenen