views:

1261

answers:

4

It's my first time using a DVCS and also as a lone developer, the first time that I've actually used branches, so maybe I'm missing something here.

I have a remote repository from which I pulled the files and started working. Changes were pushed to the remote repository and of course this simple scenario works fine.

Now that my web application has some stable features, I'd like to start deploying it and so I cloned the remote repository to a new branches/stable directory outside of my working directory for the default branch and used:

hg branch stable

to create a new named branch. I created a bunch of deployment scripts that are needed only by the stable branch and I committed them as needed. Again this worked fine.

Now when I went back to my initial working directory to work on some new features, I found out that Mercurial insists on only ONE head being in the remote repository. In other words, I'd have to merge the two branches (default and stable), adding in the unneeded deployment scripts to my default branch in order to push to the main repository. This could get worse, if I had to make a change to a file in my stable branch in order to deploy.

How do I keep my named branches separate in Mercurial? Do I have to create two separate remote repositories to do so? In which case the named branches lose their value. Am I missing something here?

+2  A: 

You wrote:

I found out that Mercurial insists on only ONE head being in the remote repository.

Why do you think this is the case?

From the help for hg push:

By default, push will refuse to run if it detects the result would increase the number of remote heads. This generally indicates the the client has forgotten to pull and merge before pushing.

If you know that you are intentionally creating a new head in the remote repository, and this is desirable, use the -f flag.

Jim Correia
Is this the accepted practice? Is having multiple heads on the the remote repository okay?
Praveen Angyan
I've seen a couple of blog posts mention that it is bad practice to have multiple heads in a shared repository and this makes sense.
Praveen Angyan
+1, thanks for pointing me in the right direction.
Praveen Angyan
Having multiple heads on the same branch in a shared repository is a potential point of confusion. Having multiple heads, one per named branch, doesn't lead to the same sort of issues, as long as all of the developers sharing the repos are aware that named branches are in use.
Jim Correia
+4  A: 

After re reading the section on named branchy development in the Mercurial book, I've concluded that for me personally, the best practice is to have separate shared repositories, one for each branch. I was on the free account at bitbucket.org, so I was trying to force myself to use only one shared repository, which created the problem.

I've bit the bullet and got myself a paid account so that I can keep a separate shared repository for my stable releases.

Praveen Angyan
What made you conclude that? I don't see anything in there that says "Named branches are bad". I personally think they're far easier to work with than multiple repositories.
Steve Losh
"In most instances, isolating branches in repositories is the right approach. Its simplicity makes it easy to understand; and so it's hard to make mistakes. There's a one-to-one relationship between branches you're working in and directories on your system. This lets you use normal (non-Mercurial-aware) tools to work on files within a branch/repository." - From the Mercurial bookPersonally, for me the suggestion given above leads to a simpler mental model. I've modified my reply as well.
Praveen Angyan
Ah, I guess I don't agree that that makes things simpler. What if your code needs to be in a specific location on your filesystem? Do you copy/rename folders every time you want to switch branches? If someone wants to get all the branches in a project, should they really have to clone the entire thing multiple times?
Steve Losh
AFAICT, the only way to deal sanely with multiple branches of code with hard path requirements where not all branches should be pushed is either to maintain the masters in an alternate location and 'hg strip 0 ; hg pull branch' as needed, or simply use git. Mercurial doesn't seem to support disposable named branches outside of the somewhat clunky mq system (or if it does, I'd love to see documentation on how it is supposed to work).
Zed
**@Zed** What's wrong with `hg push branchname-to-push`? Only push branches you want to push. If you want a disposable branch, just don't push it and then strip it once you decide you don't want it anymore.
Steve Losh
Oops, make that `hg push -r branchname-to-push` in the last comment.
Steve Losh
+5  A: 

Use hg push -f to force the creation of a new remote head.

The reason push won't do it by default is that it's trying to remind you to pull and merge in case you forgot. What you don't want to happen is:

  • You and I check out revision 100 of named branch "X".
  • You commit locally and push.
  • I commit locally and push.

Now branch X looks like this in the remote repo:

--(100)--(101)
     \
      \---------(102)

Which head should a new developer grab if they're checking out the branch? Who knows.

Steve Losh
I think the developer should clone the entire repository and update to the X branch. He would then end up at revision 102 (the tip-most revision on X). The developer can then simply merge the two heads if he knows how, or he can leave that to someone else.
Martin Geisler
A: 

I've come from git expecting the same thing. Just pushing the top looks like it might be one approach.

hg push -r tip

Pinballkid