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