5

I've been using git for quite some time, and just changed to mercurial to use kiln. Issue here is that git branch is an essential part of my development strategy. I usually have 2 or 3 branches at any moment and change between them. How can I do this with mercurial ? I looked at bookmark's but changing between bookmarks is just not possible, can anyone explain. This is the #1 point on: http://whygitisbetterthanx.com/ And I concur, without this mercurial is almost useless for me.

flag
Have a look at the blog page linked from kiln.stackexchange.com/questions/2437/… – CADbloke Nov 6 2010 at 12:31

2 Answers

9

Steve Coffee gives absolutely phenomenal advice for using named branches, and I'm very happy he's an active user on the Kiln forums, but I respectfully disagree that Mercurial's native branches are exactly equivalent to Git's branches—especially if you're a user coming from Git.

I'm going to ignore Mercurial's named branches for a moment, and focus purely on what Git users usually mean when they talk about branches (since it's the only form Git supports), which is "lightweight" branches.

Git branches are really just named heads. You've got a DAG, it has multiple heads, and each one has a name. Git has a concept that you can be "on" a given head, which means that when you commit, that head is "advanced"—i.e., will now reference your latest commit.

As Steve notes, Mercurial works this way just fine. The only difference is that you don't have to name the heads by default, so whereas in Git I'd have to immediately name whatever little branch I'm doing, Mercurial does not make me do that. These branches are all "anonymous heads", and Mercurial users do this all the time (usually with bookmarks—more on that in a second) to do lightweight experimental branching.

If you want to name your heads, you can use the bookmark extension. Contrary to what you apparently read at GitHub's evangelism site, it's very easy to jump between bookmarks. The command is simply hg update <bookmarkname>. If you switch bookmarks into track mode, the behavior will even directly mirror what you're used to in Git, which is that there is a single "active" bookmark, just like Git has a single active head. Nearly every Fog Creek developer (and to my knowledge all Kiln developers) make heavy use of this workflow.

So if you generally just do local branches for experiments, anonymous heads or bookmarks really should be a direct analog for what you're used to in Kiln.


That takes us to what happens when we need to interact with the server. Git's insistence that all heads be named does make it do one key thing very differently from Mercurial: Git by default pushes only the "active" head, whereas Mercurial pushes all heads. Whether you use Mercurial's named branches, anonymous heads, or bookmarks, this difference holds.

The good news is that we're talking about defaults, not The One True Way. You can tell Git to push all heads every time, and it's easy to add a command called hg nudge that only pushes the "active" head.

And this comes up to why Kiln doesn't encourage the use of named branches: we like the Git style of development a bit more. We like to have control over what we're pushing, rather than pushing all branches at once, and just because something started as an experiment, we don't really care about that fact when going through the history. Mercurial's native named branches record the branch name in the commit itself, which means that once it's there, it's there. While hg nudge will prevent that branch from going out until I merge it (if ever), once I do merge it, it's there, preserved forever in the repository history, and will always be something I can hg update to.

This is personal preference. Steve Coffee has gotten tremendous leverage out of Mercurial's native named branch support, and we're working actively right now to figure out how to vastly increase Kiln's support of named branches in a very near release. For the above reasons, the Kiln team itself doesn't like them.


Of course, we still like having multiple heads in our local repository. We don't have to have three clones each for Kiln 2.0, Kiln 2.0SP1, and Kiln 2.1. And that's where Kiln's branch repositories combine really nicely with bookmarks to get the job done.

What we do is have separate repositories on the server for these kind of major releases. But (most of) the Kiln team only has a single clone for each general concept. What we'll do is pull from each of those repositories into a single clone, use bookmarks or hg-remotebranches to tag which head is which, and then just hg update to the head we want to make the fix on as we work. When we find ourselves doing an experimental effort that's not quite ready to go out, we add a new bookmark for the anonymous head, make a new branch repository in Kiln, and push that one head there. This gives all the benefits of having lots of branches in a single repository, without cluttering up the history with branch names we don't care about, or making it difficult for us to "throw out" history when we have a change of heart.


So Mercurial's branching model is if anything more powerful than Git, simply because there are many more ways to accomplish variations on a theme.

Git-style lightweight branches are there through anonymous heads and bookmarks.

Git-style lightweight remote branches are there through the above, plus Kiln-style branch repositories.

Permanent historical branches, which lack a Git analog, are available through Mercurial's native named branch support.

All three work both for long-term release management and short-term feature development, with different features and trade-offs.

link|flag
I agree 100% Benjamin, and thanks for the clarification on the differences between git and hg branching, especially regarding pushing. My main point was that they are functionally equivalent to the extent that a development process that uses git branching will work just fine with mercurial native branches. – Steve Coffee Oct 31 2010 at 1:10
I look forward to the improved support of named branches, although honestly, Kiln is a great product and we love it as is. I think by far the biggest issue with named branches is that the official position is to actively discourage them. Most developers coming from the git world probably come to the same conclusion as our questioner if they delve no deeper than the introductory Kiln docs. The fact that you include an extension to prevent native branching makes it even more difficult for new users to get past this. – Steve Coffee Oct 31 2010 at 1:18
I hope the anti-native-branch official position is one of the things that you are considering changing. It does none of us any good for potential members of the Kiln/Mercurial community to be warned off unnecessarily simply because their development process is closer to ours than to yours. – Steve Coffee Oct 31 2010 at 1:21
4

Mercurial's native branches are functionally equivalent to git branches. The problem with Kiln's implementation (and to a lesser extent the Mercurial community in general) is that they create full repository clones and insist on calling that "branching" instead of "cloning". This causes a great deal of unnecessary confusion, of which your question is a prime example.

Native branches come in two flavors in Mercurial: named and anonymous.

You can easily create anonymous branches by simply updating your working directory to a node that already has a child and committing a new change there.

A named branch can be created at any node with an explicit command. This is most similar to git, but the implementation is slightly different. Mercurial's docs on named branches may be helpful.

The primary drawback is that deleting a branch is nontrivial (but possible) in the current version of Kiln and Mercurial.

More details here and here.

link|flag

Your Answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.