[PATCH 0 of 9] improvements for named branches

Alexis S. L. Carvalho alexis at cecm.usp.br
Tue Mar 4 00:08:19 CST 2008

First I have to ask (and give my version of the answers):

What are some use cases that you see for named branches?

  - long-lived branches like stable

  - some feature that would take a longer time to develop, and so is
    kept somewhat separate from the main development

  - in general, if somebody doesn't want to make a full clone, I'd like
    to have a way to have multiple lines of development in the same
    repo, without having to manually keep track of hexnodes.  Maybe
    named branches will still be too heavy for this even after more
    changes, but I'd like to try to make them more useful for this case

When would one want to close/inactivate/... a named branch?

  For long-lived branches, never.

  For the other cases, when the work is ready to be merged into the main
  line of development.  In particular, closing of branches would happen
  mostly in merge revisions.

  If that line of development was considered a failure...  Well, without
  named branches the usual recommendation is to "discard" that head
  using merge+revert, which could also be an option here.  And then the
  branch could be closed during the merge commit.

What does it mean to close/inactivate/... a named branch?

  To make it look as if that name never existed (but you could still
  recalculate them if you're doing archaeology).

Thus spake Matt Mackall:
> On Sun, Mar 02, 2008 at 04:01:22PM -0300, Alexis S. L. Carvalho wrote:
> > "Closing a branch" essentially means to remove it from the branch cache,
> > which means that its name won't be recognized anymore, effectively
> > hiding it.  I like "close" better than "remove" or "delete", since we're
> > not actually removing anything from the repo itself.
> How do you unclose a branch? For example, if some bonehead closes
> stable using merge --close?

Just add another revision to that branch.  These patches close specific
heads of a named branch.  If there are others (or if you add others
later), the named branch will still be open.

>                             Merge --close is a bit worrisome and so is
> the non-locality of the closures is as well.

I don't see what's the problem with merge --close - actually, for what I
have in mind, using a merge commit would be the most convenient way to
close a branch.

My main argument for the non-locality is that it makes it easier to fix
user errors.  Also notice that a revision can only close heads of a
named branch that are its ancestors (i.e. it's non-local, but it's
not completely unrestricted).

>                                              How do I find commits
> where the close happened so I know who the bonehead is?

Right now you can't, but see below.

> Also, what happens if you do:
> hg branch --close thisbranch

abort: refusing to close current branch "thisbranch"

> hg add newfile
> hg ci

Even if you manage to dodge the check above, the new commit would say
that its parent is closed, but the new commit itself would be a new head
of that branch.  I.e. things would work as if nothing had been closed.

> Also, how do you unclose a branch before commit?

Right now with a very well hidden hg branch --close ''

> I'd rather require an explicit commit on the branch head(s) to move it
> to the "inactive" state. Then a "closed" branch is one where all its
> heads are inactive.

You mean something like extra['branch'] = 'foo'; extra['closed'] = 1
would mean that this commit should not be considered an open head of the
named branch "foo"?

>                     I think this should look something like:
> $ hg branch
> foo
> $ hg commit --close-branch 
> abort: there are outstanding changes
> $ hg revert -aq
> $ hg commit --close-branch -m "foo is dead"
> $ hg branch
> foo
> $ hg add newfile
> $ hg commit -m "foo is risen"
> (We'll have to check that our parent's branch is also foo, otherwise,
> we're doing a no-op: opening and closing a branch head simultaneously.)
> Moving closing to commit simplifies things a bit - we don't have to do
> any special storage of the "close" intent, we don't need a way to
> display or erase that intent, and we don't have to check all our other
> actions against that intent.
> This is different than starting a branch, where it makes sense to
> actually change a few things before committing (like version
> identifiers). Also, we encourage people to explain why they close
> branches by making it the sole contents of the commit (and not having
> a default message).

What I don't see is:  when would you want to close a branch and leave
that repository head around?  And if you want to "discard" that head
with merge+revert, you'd have to

hg up -C default
hg merge foo

But would hg still recognize the name foo?  I guess "tip" would also
work in this case...

> Finally, I presume you intend it to be possible to find closed
> branches with the branches command? 

Only with some extra flag that would require a full rescan of the
changelog.  And then this could also display the commit that closed each
head .

>                                     What happens if you attempt to
> merge with a branch that has one open head and one closed head?

We wouldn't see the closed head at all, so we'd just use the open one.

>                                                                 I
> really don't like that you've made branch names ambiguous. Tags are
> not ambiguous, 'tip' is not ambiguous, and I don't think branch names
> should be either. There should instead be a precedence ordering. If I
> say "merge with foo", the open branch head closest to tip is what I
> should get.

My main fear is that this could lead to people accidentally ending up
with multiple heads in a single named branch - but improving the checks
on push might be enough here.

What I think is important is to have pull/push/clone -r transfer all the
heads of the repo and have log -r show all the heads.  In general, make
all commands that can operate on multiple revisions operate on all the


More information about the Mercurial-devel mailing list