effective use of in-repository branching

Stuart Marks Stuart.Marks at Sun.COM
Wed Feb 7 20:39:19 UTC 2007


Some colleagues and I have been discussing the use of Mercurial's named-branch 
feature to keep patches and mainline development in the same repository. Named 
branches seem almost ideal for doing this, but there are a couple stumbling blocks.

For example, suppose we have the following sequence of revisions:

81----82(1.0)----83----84(tip)

Let's say that rev 82 corresponds to a 1.0 release of the project, so it was 
tagged as such. Post-1.0 development continues with revs 83, 84, and so on.

Now let's say that we need to issue a patch for 1.0 but we don't want to mix in 
the work-in-progress from revs 83 and 84. We'd update a working copy to rev 82, 
implement the patch, and commit it with a new branch name. This would result in:

81----82(1.0)----83----84
         |
         |
         +----85[1.0patch](tip)

Structurally, this is perfectly correct. However, there are some things about 
the situation now that seem quite inconvenient.

(1) Common usage is for developers to do "pull -u" to keep up to date with a 
shared repository. Unfortunately, this updates to the tip, which is now on a 
branch. If a developer's repo is at rev 83, then "pull -u" will now result in 
something like:

abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes

This is proper behavior, since we don't want to switch branches automatically. 
However, it forces the developer to update manually, which undermines the 
usefulness of "pull -u".

Instead of updating to the tip, maybe update and pull -u should automatically 
update to the most recent head of the current branch, something like "hg update 
$(hg branch)". If we have to give the mainline an explicit branch name, that 
would be OK. I note that the BranchPlan wiki page has the following item:

    * if a branch is set, update should update to the tip of the current branch

Does this mean the same thing as I said? If so, then consider this my vote for 
this feature.

(2) Returning to the state of the repository as diagrammed above, suppose a 
developer creates a new repository with clone or pull and then dives into 
development. This is a mistake, since the tip is on the patch branch instead of 
on the mainline.

We can work around this by telling everyone to make sure to run "hg update -C 
mainline" before beginning work. Or, we can tell everyone who pushes changes to 
make sure that their last commit leaves the tip at the end of the mainline. 
Either seems quite troublesome.

It seems that the root cause of these problems is that several hg operations 
default to using the tip, but the tip can bounce around from branch to branch. 
It would be nice if there were a way to modify hg to update to something else 
instead of to the tip.

This was discussed a bit last month; see the mail archives for January 2007 and 
look for messages with the subject "Needs for a default branch". Unfortunately 
some of the proposals were quite heavyweight, and the thread didn't seem to 
reach any reasonable conclusion.

It seems to me that a very lightweight notion of "default branch" would be 
useful. I guess this would be stored in .hg/hgrc. It would have the following 
semantics:

a) Cloning a repo would propagate the default branch (if any) into the new 
repo, and then update to the default branch (if any), otherwise to the tip.

b) If the working copy has no parent, "hg update" and "pull -u" update to the 
default branch instead of to the tip.

This, combined with (1) above, would make in-repository branches much more 
useful and much less error-prone.

What do you think?

s'marks



More information about the Mercurial mailing list