In Mercurial, what's the difference between a 'head' and a 'branch'? - mercurial

I'm new to Mercurial, and DVCS in general. What's the difference between a head and a branch?

If you view it as a tree, then a head is a leaf, at the very end of a branch.
It's explained really well at Mercurial's own wiki:
Branches
Heads

The answer is "it depends". Mercurial has four different branching strategies from which you can pick, and depending how what you're choosing to call a branch the answer can be anything from "they're unrelated" to "they're the same thing".
First look at the four types of branching:
named branches
bookmarks as branches
anonymous branches
clones as branches
Hit the link if any of those are unclear to you.
Looking then at each of those let's see how a head and a branch are related:
named branches - completely unrelated. you can have multiple heads per named branch, and not every named branch needs to have a head
bookmarks as branches - mostly unrelated. bookmarks can point to heads or non heads, but they move to the "new head" when you commit
anonymous branches - heads are branches in this model. They're unnamed and very light.
clones as branches - heads are branches, but you're more likely to have them in separate repos than in the same repo. You pull/push and then merge down to one in that repo.
TL;DR: You need to understand both heads and branches to use a DVCS well.

From the wiki:
head a changeset that has no children
branch the set of all changesets with the same branch name
Every changeset belongs to a branch, default if not specified.
If you're new and looking for a quickstart, I recommend hginit.com.

It's hard to point out differences, because these are orthogonal concepts. They are explained in the Mercurial wiki, which has
an entry for Head and one for
one for Branch.

Related

mercurial graft feature, can it copy?

there is a new feature in mercurial 3, called 'graft' (graft to local).
it does a good job of moving a change-set to a different branch.
Is there a way to "COPY" a change-set to a branch?
I am interested in in moving stuff from the QA branch to the production branch, but I still need the code to reside in QA. So what I really want is a copy. I just found this and have only tried a few things, maybe it'll all become clear with some more tinkering and reading...
Does anyone have a better way of 'cherry picking' change-sets to move cross branch (or trunk)???
Graft copies changesets, it doesn't move them. From hg help graft (emphasis mine):
This command uses Mercurial's merge logic to copy individual changes from other branches without merging branches in the history graph. This is sometimes known as 'backporting' or 'cherry-picking'. By default, graft will copy user, date, and description from the source changesets.

Is a workflow of hg clone on non-bare hg repositories safe?

I know that git will refuse to push to a non-bare repository, but hg doesn't seem to... Does that mean that I do not need to worry about bareness when cloning with hg? I've experimented (in pastebin below), and I haven't seen any problems with this approach, but my inability to find problems is not the same as there being no problems. Also, I have autopush enabled in my .hgrc...
http://pastebin.com/qZyyqb6p
Mercurial does not auto-merge anything when you push, so pushing to a non-bare repository is completely safe. This is why Mercurial does not distinguish between bare and non-bare repositories - a bare repository is simply one where the working directory is at the null revision (i.e. before the initial commit).
If you are pushing a new head to an existing branch Mercurial will require you to specify hg push -f. This is because having multiple heads on the same branch imposes additional complications for other developers and could potentially result in the heads being merged in different ways, leading to a cascade of unnecessary merges.
The workflow you should generally follow is pull; merge your new heads to the existing head; push. Of course, this also depends heavily on the branching strategy you are using - one which uses bookmarks (equivalent to git branches) or anonymous branching for tasks will often end up with multiple heads on the same named branch, whereas one using named branches for tasks tend not to.

Mercurial Closing a Branch

I have been using named branches both as feature branches and long lived branches. I just merged a bunch of feature branches into a long-lived branch, so I no longer need those feature branches muddling up the history graph (although I still want to keep the commit messages of course).
How do I do this?
Checkout the branch (hg co branchname) then hg commit --close-branch to mark the branch "closed".
Branches in mercurial are permanent, which is why they're a good choice for things that live forever like "release 1.0" and "experimental". For features you might want to consider something more transitory like bookmarks, clones, or anonymous branches. All four options are very well described here: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
As #wolvever shows you can hide it from a list, but you can't get rid of it without making your repo a different repo entirely (and thus breaking all clones).

What is the purpose of closing a branch

I was wondering, what is the purpose of closing a branch. As for issue-1 branch, I had already close. But
I still can see issue1-1 in my revision graph
I still can switch to branch issue1-1, and continue to commit.
So, what is the whole point of closing a branch?
See: https://www.mercurial-scm.org/wiki/PruningDeadBranches
It is informational so that hg branches will show that these branches are closed. And hg heads --active will not display any heads that are marked closed.
In a long run, number of branches can be considerable and can add to informational noise. This is a good way to prune some of those noise.
This is exactly why named branches probably aren't the right choice for per-feature and per-issue branches -- you can hide them but you can't eliminate them. Consider reserving named branches for long-lived concepts like 'stable', 'experimental', etc. For per-issue and per-feature branching either anonymous branches, clone branches, or bookmarks are better solutions. They're all described wonderfully here:
A Guide to Branching In Mercurial.

Can I branch in Mercurial without cloning the repository?

Recently, I've started experimenting with Mercurial, due to the fact that it always attracted it because of its simplicity and "just works" principle. Or at least, that's how others always described it.
They also usually described it as "practically the same as git with just a few minor changes you won't notice" - only for me to discover it isn't quite so.
I'm having problem with Hg branches. Pardon me if this is an overly simple question, but in git one has a working directory and a repo (.git). In the repo one has revisions, and branches, and can jump from one to another.
I'm having trouble finding a similar model in Hg. As far as I can see, for Hg to have a "branch" one needs to clone a repo to another directory? Is there a way Hg could work just like git does - i.e. one working dir., and one repo, in which you can do things as regard to branching and revs?
Mercurial supports a very rich set of ways to branch. See http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
In brief, you can create a named branch by running
hg branch NewBranch
and switch to that branch using
hg up NewBranch
or switch back to trunk using
hg up default
In Mercurial, if you go to any particular revision, you can always edit your working copy and commit, thereby making another "head." Merging works on head revisions by default. You can use hg head to see what heads are in your repository. This seems to be the most "idiomatic" way I have found branching to work in Mercurial.
Take a look at section about branches in my answer to "Git and Mercurial - Compare and Contrast" here on StackOverflow.
The information about various options available for branching in Mercurial (anonymous heads, not-propagated (I think yet still) bookmarks, and global (world-wide) commit labels aka named branches) was taken from http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/, and expanded using feedback on #mercurial IRC channel on FreeNode.