Branches in general

Matt Mackall mpm at selenic.com
Sat Jun 9 16:27:39 CDT 2007


On Sat, Jun 09, 2007 at 12:56:06PM -0700, Eric M. Hopper wrote:
> On Sat, 2007-06-09 at 13:28 -0500, Matt Mackall wrote:
> > On Sat, Jun 09, 2007 at 09:57:42AM -0700, Eric M. Hopper wrote:
> > > On Fri, 2007-06-08 at 20:19 -0700, Brendan Cully wrote:
> > > 
> > > > As you know, I also have my doubts about hg's branches, but I'd be
> > > > curious to know what the specific drawbacks were, and how current the
> > > > implementation was. Most of the UI work to make branches halfway
> > > > reasonable happened after 0.9.3 was released. Some of it is only a few
> > > > days old...
> > > 
> > > 
> > > Here is one concrete problem...
> > > 
> > > A revision can be in more than one branch at a time.
> > > 
> > > The specific case of this is fast-forward merge:
> > > 
> > > 
> > > A1--A2--A3        A4------A5
> > >          \        /       /
> > >          B1--B2--B3--B4--B5
> > > 
> > > 
> > > So, in this case, what you really did when you merged B3 is that you
> > > said that B1->B3 are now also part of branch A.  Because Mercurial
> > > associates one branch per revision, this is not possible to represent,
> > > and so an artificial revision is created on branch A to represent this.
> > 
> > In some sense it's artificial, yes. No files are touched, etc. In some
> > sense it's not: declaring that the changes in B3 are now part of
> > branch A is an event. It has a time, it has an associated user, and it
> > may have a non-trivial description.
> 
> Usually I don't want to know this.  I can see some cases in which it's
> an event worthy of the world knowing about, but mostly I don't think it
> is.

You don't want to know this.. *ever*? The alternative that people are
proposing is -no history-.

> In fact I think this sometimes can obscure important things

Be specific about these "things" or this will continue to get nowhere.

> > There is?
>
> Yes, for example when you grab a branch head you can get revisions with
> branch comments stating that they're from all kinds of other random
> branches.  They just happen to be ancestors of the head of the branch
> you wanted.

[Damnit, don't delete the context. I've just come from reading 1000+
LKML messages and I have no idea what you're responding to any more.
Oh, ok, this is the "heuristic that everything that's an ancestor is
on a branch".]

Uh, so? Why does this matter? Just ignore that field in the log if it
bothers you so much - the proposed alternative (git-style) doesn't
have this information so you should be happy. Or would you rather
report every branch that a changeset is a member of? Possible, but
expensive.
 
> When you create a new branch, suddenly all the changes that are
> ancestors of it are on your new branch no matter what branch tags they
> may have in their revisions.

Which makes your working definition of "branch" (all ancestors of
branch tips) not very interesting, IMO. Was commit 500 in the hg repo
on the stable branch in any useful sense? Sure, it shows up in the
stable release, but it predates the existence of the concept of the
stable branch by a year or so.

A related question is whether the changesets in -stable are in -main.
Well the answer of course is yes because we merge stable into main
regularly. We can see that by following the log of -main. It would be
more convenient to have a command to answer this question (is x an
ancestor of y?). But we can also answer the fairly important question:
in what context was this patch developed?
 
> > > My heads -b code makes fairly explicit use of this heuristic in
> > > guessing about branch heads.
> > 
> > It does? What's there to guess? A head of the sub-DAG X (aka "branch" X)
> > is any node in sub-DAG X which does not have descendents in
> > sub-DAG X.
> 
> Well, I might misidentify a head.  I might call something a head when in
> reality nobody should ever really develop on that branch from that
> revision ever again.

People have to go out of their way to find those heads and check them
out so I don't really consider that a problem. Nor is it terribly
catastrophic if they do. It might be interesting to talk about ways to
"close" old heads. Your "active" heuristic isn't bad.

> And I might also miss calling something a head
> because it doesn't have a branch tag that says it's on that branch, but
> from the perspective of anybody who's doing development it actually is a
> head for that branch.

Like B3? If you look at this graph:

S1-S2-S3           
        \ 
         F1-F2-F3  

F3 is *not* the head of S. The head of S is S3. You wouldn't want F3
to be head because "F" here stands for "feature" and "S" stands
for "stable". Compare:

S1-S2-S3          S4   (stable)
        \        /
         F1-F2-F3      (feature)

An explicit action is needed to pull the work on the feature branch
into the stable branch. And that's a good thing.

Without per-changeset branch tags, we have:

             unrecorded
    S     F    action             S,F
    v     v      ->                v
1-2-3-4-5-6              1-2-3-4-5-6

Notice how much less information is in this last picture. Was 4
developed on the stable branch? That information is forever lost.

--
Mathematics is the supreme nostalgia of our time.


More information about the Mercurial-devel mailing list