Branches and Heads

solo turn soloturn at gmail.com
Wed Feb 21 04:11:13 UTC 2007


why a label is called a branch and a branch is called something else?
maybe it would be good to let "commit" do an pull so you can really
train your brain :)

-solo
-------------------
mercurial - brainware

On 2/16/07, Stuart Marks <Stuart.Marks at sun.com> wrote:
> Russell Suter wrote:
> > If I create a branch on a branch it appears that there is only
> > one head for both branches -- the head is on the second branch.
> >
> > 10
> > |
> > +--11 (branch 1)
> >     |
> >     +--12 (branch 2) (head) (tip)
> >
> > If I set back to branch 1, the branch command reports that I'm
> > on branch 1 as expected but the revision is revision 12 even if
> > I do an update -C.  If I update to revision 11 and commit a change
> > (creating revision 13) the heads command will show that I have
> > two heads:
> >
> > 10
> > |
> > +--11--13 (head)(tip)
> >     |
> >     +--12 (head)
> >
> > What I would expect is that revision 11 stays the head of branch 1
> > even when branch 2 / revision 12 is created.  Also, when I go back
> > to branch 1 and update, I get revision 11.
>
> It sounds like you're thinking that 'hg branch' actually creates branches. This
> is understandable, since hg's branching doesn't really seem to be described
> very well anywhere.
>
> As I understand it, 'hg branch' merely sets or gets the branch name of the
> working copy, which is significant only when a commit is done. At that point
> the rev created by the commit has a branch label associated with it. This
> doesn't affect the topology of the history tree in any way.
>
> Also, 'hg branch' doesn't change the parent rev of the working copy. You have
> to do an 'hg update' to do that.
>
> To create a branch explicitly, you need to update the working copy to a
> non-head rev and commit a new rev there. This occurs regardless of whether
> you've set a branch name with 'hg branch'. If you have, you've created a named
> branch; otherwise you've created an unnamed branch.
>
> A "head" is simply a description of where a rev is in the history tree. If a
> rev has no children (i.e., it's a leaf node) it's a head, otherwise not. This
> is independent of whether it has a branch name.
>
> In your example, I think you did the following:
>
> $ hg parent
> changeset:   10:ea198e780bce
> tag:         tip
> ...
> $ hg branch "branch 1"
> $ hg commit                # creates rev 11, labeled "branch 1"
> $ hg branch "branch 2"
> $ hg commit                # creates rev 12, labeled "branch 2"
>
> If so, then you're simply adding new revs to the tip. This gives a linear
> sequence of revs, with no branches, that happen to have a couple different
> branch labels. Since rev 11 is now an interior node in the history tree, it's
> not a head.
>
> As you observed you can update back to rev 11 and commit a new rev there, which
> truly creates a branch. You can also do 'hg update "branch 1"' which will
> update the working copy to the tipmost rev with that branch name, whether or
> not that rev happens to be a head.
>
> > To complicate matters, if I do this in a clone of a parent repository,
> > when I go to push revision 13, It aborts with the "push creates new
> > remote branches!" message.
>
> Right, doing a push that creates a new head is unusual enough that push warns
> about it. This is often the case if you did a pull that had a conflict that you
> forgot to merge. But if it's truly your intent to create a new head in the
> parent, just use push -f.
>
> s'marks
> _______________________________________________
> Mercurial mailing list
> Mercurial at selenic.com
> http://selenic.com/mailman/listinfo/mercurial
>



More information about the Mercurial mailing list