Local Branches

Named branches are nice for long-lived branches (eg stable vs development). But sometimes you want to create short-lived branches, perhaps to develop a feature. Once the code has matured to the point where it is ready for mainline, the history of its development is often just uninteresting clutter. The usual answer is to use Mercurial's nice lightweight clones. But even these require duplication of the working directory for each branch, and often other setup work (configure runs etc).

Local branches are clones that live within a repository, allowing you to share one working directory across several branches, but then to be able to drop those branches trivially when you are done with them.

Mechanism:

An experimental extension is here: http://hg.kublai.com/mercurial/extensions/localbranch

Interesting conversation

So, on 2007-06-07 at 19:02 UTC -0700 BrendanCully and I (EricHopper aka Omnifarious) had this interesting conversation on IRC #mercurial:

19:02 Omnifarious I'm wondering if anybody has a good reason not to push my change to crew. :-)
19:23 brendan I personally just haven't thought enough about it. I have this bad feeling there's a nicer way to do this...
19:51 Omnifarious So, from a UI perspective you might well be right.
19:51 Omnifarious I suspect you are. I think the way the command line options here are organized isn't really the best that could be done.
19:51 Omnifarious But, from an internal mechanics perspective, I don't think there's a better way to do it.
19:52 Omnifarious I actually find the whole branch idea rather suspect. Mostly because I think a branch is a piece of repository level information that does not belong indelibly recorded in a revision.
19:53 Omnifarious I think the fast-forward merge problem is actually a really great illustration of the disconnect here.
19:56 brendan yes, that's tricky. I am hoping the localbranch stuff will help
19:57 brendan something I haven't put my finger on bothers me about hg's named branches too
19:57 Omnifarious I think sometimes though that people have to have something to play with for awhile to know what they really want.
19:57 brendan I think it can work fine for 'stable' vs 'devel' though
20:01 brendan git's branches are nice in that they're throwaway, but I don't think it's very good about exporting things. I recall a lot of manually set up branch maps
20:01 brendan and there seems to be a bit too much rebasing
20:01 Omnifarious Mercurial in general has shyed away from copying repository meta-data between repositories.
20:02 Omnifarious I think that branches are repository meta-data, not data about revisions. And I think it needs to be copied form repo to repo by pull, push, clone and other such utilities.
20:03 Omnifarious I think a branch is mostly a label you've applied to a set of heads.
20:03 brendan I don't think they're much different from tags, which are propagated
20:04 Omnifarious Yes and no.
20:04 brendan I don't know about this 'active branch' idea though. I think making active == 'has heads' is probably wrong.
20:04 Omnifarious Hmm...
20:05 brendan I suspect we may need to mark them manually
20:06 Omnifarious So, here is why I think branches are different than tags....
20:06 Omnifarious Tags are a fact about a particular revision.
20:07 Omnifarious Once that fact is recorded, it doesn't change.
20:07 Omnifarious A branch is something that's about a group of revisions and future revisions.
20:07 brendan we do have some logic for tag movement though
20:08 Omnifarious Yes, but it's not like the tag is ever applied to two revisions at once.
20:08 brendan hmm
20:09 Omnifarious I don't know... do people ever have a 'latest stable release' tag that just gets updated all the time instead of labeling each stable release with a different tag?
20:10 Omnifarious Even then that feels fundamentally different from a branch which seems a much more distributed and amorphous idea.
20:10 brendan don't know. seems plausible though
20:11 brendan well, a branch is basically a distinct changelog, but we need a way to make them live together
20:18 Omnifarious I sort of think of a branch as being a little piece of meta-data about a particular repo.
20:19 Omnifarious It's like "Hey, when we put stuff here, it's for this."
20:21 Omnifarious And if you pull from a repo that isn't for that purpose, those changes should be invisible by default in your repo.
20:21 Omnifarious Hmmm...
20:22 Omnifarious So, here's a concrete idea...
20:22 Omnifarious There is no data about branches in any individual revision.
20:23 Omnifarious It exists solely in the branch cache, which can be propogated between repos.
20:23 brendan this recalls the old idea of having a .hgbranches file
20:24 Omnifarious But this branch cache is not version controlled.
20:24 Omnifarious A repo updates it based on a set of distinct rules when a new version is committed or a revision is pulled.
20:24 brendan hmm. you might get some pushback about that.
20:25 brendan I remember mpm being of the opinion that propagation in hg was best done through the version control mechanism
20:25 Omnifarious Each branch cache entry consists of a branch name and a set of revisions that are considered heads.
20:25 brendan the mq nested repo approach might work around that though
20:26 Omnifarious If a new cache entry is recieved for a particular branch it removes any cache entries for revisions that are ancestors of the new entry.
20:26 Omnifarious You also have a 'working branch' recorded like the dirstate.
20:27 Omnifarious And by default all commands only show you data about the 'working branch' if one is recorded.
20:27 brendan sounds like you're replacing the heads algorithm
20:27 brendan also sounds like it's going to look like localbranches
20:27 brendan !localbranches
20:27 hgbot brendan: Error: "localbranches" is not a valid command.
20:27 brendan !whatis localbranch
20:27 hgbot brendan: "localbranch" could be http://www.selenic.com/mercurial/wiki/index.cgi/LocalBranches
20:29 Omnifarious Yes, it's very much like that idea. Except with the added feature of having them propogate between repositories.
20:29 brendan yes, that's a bit I wanted to add in
20:30 Omnifarious I think all branches are 'short-lived'. You might have a recurring development branch that forks off, but it always comes back to the stable branch.
20:31 codemac I think that is a massive assumption about how others see their branches
20:31 brendan otoh I think short-lived branches can be very handy
20:32 brendan would be nice to support them. I've got some time to myself this weekend and I hope I can take another crack at the localbranch queue
20:32 brendan I think transient branches are the biggest thing git users miss in hg
20:33 brendan transient branch by cloning can be a bit annoying
20:33 Omnifarious codemac: Well, I think this even accomodates long-term branches.
20:33 Omnifarious brendan: I've been meaning to re-write the little contrib thingy that relinks files that are identical.
20:33 codemac Omnifarious: I haven't checked out your code yet, I was just reacting to your statement :P
20:34 brendan Omnifarious: ok. it was a pretty quick hack
20:34 Omnifarious codemac: Oh, my code is based on the current branch model in which branches are forever and can never be forgotten.
20:34 Omnifarious brendan: *nod* I've been meaning to change it to determine if two files are identical by comparing head lists. :-)
20:35 brendan yep, that's probably a good idea
20:35 brendan I think it already only compares indices though
20:35 Omnifarious I have to disappear in a minute or two.
20:35 Omnifarious Oh, well that's a good thing.
20:36 Omnifarious Does it do a repo write lock on both repos while it's running?
20:36 brendan no
20:36 brendan it started out as a generic relinker
20:37 brendan anyway, you're welcome to make it smarter :)
20:37 Omnifarious It would reduce the annoyance of lots of clones. :-)
20:37 brendan would be cool if it could do more than pairs :)


CategoryNewFeatures

LocalBranches (last edited 2008-04-02 22:17:30 by AdrianBuehlmann)