[PATCH 0 of 9] improvements for named branches

Alexis S. L. Carvalho alexis at cecm.usp.br
Sun Mar 2 13:01:22 CST 2008


This patch series implements two features for named branches:

- multi-headed branches (patches 1-4)

- branch closing (patches 5-9)

Just like a repo can have multiple heads, a named branch can easily grow
multiple heads (two users commit stuff in their private repos and then
pull the other).  So I think it makes sense to keep track of all the
heads of a named branch.

UI-wise this means that commands that want a single revision (e.g. diff)
will complain that the name is ambiguous; commands that take multiple
revisions (pull, push, log) will use all of the heads.  The exception is
update, which will still update to the tip of the branch (but I think
I'll add a "warning: branch has multiple heads").  merge will also want
some extra smarts to be more user-friendly.

"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.

I used a field in extra ("closebranch") to save the name of the branch
being closed and another ("closebranchnodes") to save the list of branch
heads being closed.

hg branch --close foo   schedules the branch "foo" to be closed on the
next commit.  hg merge --close  is equivalent to "hg merge; hg branch
--close <branch-of-second-parent>".

It's interesting to note that saving just the name of the branch being
closed would make it hard to figure out what heads are being closed,
especially if someone reopens the branch later.  So I think we need some
pointer to the heads being closed.  It can be either an explicit list
(which is my extra['closebranchnodes']) or an implicit one (probably the
parents of the revision closing the branch).

Having an implicit list would require less code, but having an explicit
one allows the ui to be more forgiving at least in the case where
somebody wants to merge and close another branch, but makes an error:

    hg merge another-branch  #Oops, forgot --close
    hg commit -m 'merge another-branch'
    hg push

After this sequence, with an explicit list one can do just (well, it
will be possible after I allow an empty commit that just closes a

    hg branch --close another-branch
    hg commit -m 'close another-branch'
    hg push

While with an implicit list, you'd need something like

    hg up -C another-branch
    hg branch default        #or some other branch
    hg branch --close another-branch
    hg commit -m 'close another-branch'
    hg up -C -- -2           #assuming no other revision was committed
    hg merge tip             #merge the new head of this branch
    hg commit -m 'merge closing of another-branch'
    hg push

Which is a much more complicated and error-prone dance.

It also makes it easier to close ancient branches that are still opened
just because we didn't have a way to close them.

The nodes in this explicit list are automatically calculated by hg.

More than anything I want feedback on two things:

- do we want named branches with many heads?  I think we do, but somehow
  I don't think I presented the case very well...

- is this the way we want to close branches?  Or does someone have
  something else in mind?

This set is pullable from

Hmm...  I should've added a few tests for some cases that the code is supposed
to handle...


More information about the Mercurial-devel mailing list