Needs for a default branch

Jesse Keating jkeating at redhat.com
Mon Jan 8 21:29:48 UTC 2007


On Monday 08 January 2007 15:45, Mike Kasick wrote:
> Careful now.  Thinking of mercurial branches in cvs terms results in an
> impedance mismatch.

Well, I hope that this proposal doesn't just get written off because it has 
the term "CVS" in it.  CVS is horrible yes, but just BECAUSE its CVS doesn't 
mean that its wrong.  Can we ignore the fact that this usage came from CVS?

[snip]

> In this case, since mercurial isn't cvs I would find it rather
> surprisingly for mercurial to implement cvs like behavior.  Conversely,
> I would be least surprised to see mercurial implement named branches in
> a fashion that's most consistent with existing behavior.  Thus far, I've
> found mercurial's implementation of named branches to be quite
> consistent.
>
> > Now, I've been trying to come up with a way to do this with hg, and
> > I'm just not getting it.
>
> Mercurial has always (or at least, since I've started using it)
> supported intrarepository branches in the form of multiple heads.  If
> you update your working directory to a previous revision and commit a
> new change, you've forked the line of development creating an unnamed
> branch, and the repository now has two heads.

Or conversely, if you clone your repo at a given revision (hg clone -r <foo> 
repo/)

> As far as I can tell, named branches are nothing more than a way to
> attribute a "tag" that's inherited across successive commits.  If you
> apply a new branch name every time you fork your line of development,
> the named branches serve as a courtesy means to identify the two
> lineages of development.

Yes, this is still all sane.  There is in my case an FC-6 strain, soon there 
will be an FC-7 strain, and an ever present "development" strain that each 
other strain is forked from.

> > I've created a branch, committed it to a test repo.  So far so good,
> > but if I then clone that test repo, I'm automatically in the branch I
> > created.
>
> You can't be "in" a branch, only a repository.  When you clone a
> repository the working directory is updated to the tip, which is the
> most recent commit, and could have any branch associated with it.

This is where things start to get very confusing.  When I clone a repo, I 
don't want to have to "guess" at which branch I might be committing to.  If I 
clone my repo, and "hg branch" happens to show FC-6, this means that whatever 
I edit and commit will be tracked by the FC-6 branch, and may not exist in 
other branches.  But what if FC-7 branch got the last commit by somebody 
else, or the development branch?  Now I have to play games with guessing 
which branch I'm going to get when I clone, and making sure I have to update 
my working directory to the actual branch (or unbranched code) I wish to work 
on.

> > Whats more, if I made a couple branches, I always get the last branch
> > created or some such, which is very frightening.
>
> No, you get a copy of the tip, which was the most recent commit.  That's
> reasonable behavior.

But not always the most recent code.

-----main-----------------
  \             \ 
   \--FC-6       \--FC-7

Given the above little graphic, theoretically the last commit could have been 
on the FC-6 branch, and thus when a clone happens FC-6 is the active branch.  
However this isn't the newest code, that would be the main line that all 
other branches happen from.  I wouldn't want somebody cloning my repo and 
looking at the "newest" code that's actually from a year or so vintage.

> > I also can't figure out a way once I've created a branch to get back
> > to committing to the unbranched strain of code.
>
> If you have a repository with multiple heads due to a fork, there's no
> such thing as an unbranched strain, each head reflects a different
> branch.

I don't get this either.  I want to mark something as a branch so that I can 
get back to it at some point, but I want to continue development with my 
actual head.  The unnamed head if you will.

>
> > I create a branch, fix some stuff in the branch that I don't want
> > carried forward, then I want to durastically change some stuff, but I
> > can't get away from the branch I created.  hg clone -r "" doesn't
> > work, nor does clone; cd repo; hg update "".  This still puts me on
> > the named branch.
>
> You can change the name of a branch with "hg branch" and you can switch
> to a different head/branch by updating to a different revision with "hg
> update -C".  It seems that mercurial will let you do "hg branch ''" to
> stop inheriting branch names in successive commits, but it appears that
> you can't reference the most recent unnamed revision by doing "hg update
> -C ''".  You can still update to it, but you'll have to supply the
> changeset number/hash instead.

And this is good UI?

> For intrarepository branches, I would make sure that all heads
> represented named branches, and use a branch name like main, trunk,
> default, head, etc, for what would otherwise be the unnamed strain.

And how do I set one of these as the 'default' so that when somebody clones my 
repo (hg clone foo/) they get the strain of code where all the active 
development is happening, and not a strain of the codebase from 2 years ago?

> > Ideally one could make use of a default branch or even an unnamed default
> > branch.  Call it what you will, HEAD, Origin, whatever.  One should
> > expect that hg clone would reference this default branch always, and you
> > could choose a branch with -r.
>
> "hg clone" clones an entire repository including all heads, not just a
> single head.  This is the least surprising behavior.  Cloning a single
> head is a bad idea, especially since the head would be arbitrarilly
> chosen (or at best, tip, which is not what you personally want).

I'm not asking to clone just one head.  Of course I want all the heads in my 
local repodata.  However I would expect that my working directory after the 
clone would be that of the default branch, not a crapshoot of 'which ever 
branch got updated last'.

> > This seems to me to be the path of least surprise.  I asked to clone a
> > repo and without any other information, I'd expect to be in the default
> > branch (hopefully this is a builtin branch with a reserved name so that
> > when setting UP a repo, one need not define a default branch).  I
> > shouldn't have to do a clone, then update to whatever branch where
> > development is happening, and certainly I shouldn't be put into whatever
> > branch was committed to last.
> >
> > Am I really off the mark here, or do you see some value in what I'm
> > asking for?
>
> The problem is that you want mercurial to encourage a particular model
> of development that is common among cvs users (which has been adopted
> largely because the constraints of cvs).  However, such a demand for
> preference for a "default branch" is just the kind of concept that
> distributed version control packages are trying to get away from.
>
> Mercurial treats all repositories as equals, and all branches as equals.
> Unlike cvs, mercurial doesn't impose the concept of a central
> development repository, nor does it impose the concept of a default
> branch within that repository.  Furthermore, this is not without
> precedence.  Even subversion doesn't impose the concept of a default
> branch within a repository (although there is a well understood
> convention for one).
>
> Of course, mercurial doesn't forbid you from establishing a central
> repository or adopting the convention of a head development branch.

I really have to wonder if this is being different just to be different 
though.  I really like hg because it is  easy to use and understand.  If I 
have to train users of it on how to work around the random branch problem 
when they clone, I lose value in this.  Once again, just because CVS uses 
this doesn't make it by nature a flawed work model.

> > Branches really can help situations where making a myriad of
> > standalone clones for various needs is not possible, but it needs to
> > help rather than hurt.
>
> I'm a fan of the implementation as is.  Most people will never use named
> branches, especially since respository cloning is more intuitive and
> cheap.  Probably the few folks who will are folks like us where cloned
> respositories are costly or not an option.  Having a default named
> branch is inappropriate when most folks will never use such a feature.

I think its no more your place than mine to say who will use these features.  
Of course, its easier to say nobody would use a feature when it doesn't 
exist.

Personally I find value in having a deterministic approach to what branch my 
working directory will default to when I do a clone.  I want to know that if 
I don't specify a branch, my working directory will always be the unnamed 
head or a named head or something, not just whatever branch happened to be 
committed to last.

-- 
Jesse Keating
Release Engineer: Fedora
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mercurial-scm.org/pipermail/mercurial/attachments/20070108/c3b1710e/attachment-0001.asc>


More information about the Mercurial mailing list