Please note: I’m not trying to restart the argument whether Mercurial or Git is better, I just have a technical question that I, as a Mercurial user, don’t understand. I’m also not sure whether SO is the right place to ask such a question, but it is programming related.
There have been many discussions about how the two version control systems Git and Mercurial differ from each other from a user’s point of view (e.g. What is the Difference Between Mercurial and Git? and http://felipec.wordpress.com/2011/01/16/mercurial-vs-git-its-all-in-the-branches/ ), and the major difference is the handling of branches. I have read through many of these discussions, but I keep asking myself this question:
Why does Git not store the branch name as part of the commit?
I don’t really see a good reason for not doing that; it means that data can’t just simply vanish because there is no reference (tag, branch, whatever) poiting to it.
I see storing the branch in the commit as a big plus for Mercurial, because that makes it more difficult to lose data.
The main point of the Git crowd in favor of Git’s branching model, that you can simply delete branches, does not prevent Git from storing the name of the branch as part of each commit: If the commits of a branch are deleted, so are the references to that branch. It will also not interfere with the “cheap branching” argument: branches will not be more expensive to manage. And I don’t think that the additional storage needed should be of concern: it’s just a couple of bytes per commit.
One of the definitive source about branches for Git and Mercurial is the SO question:
“Git and Mercurial – Compare and Contrast“
(That allows to manage different namespaces regarding branches, for local and remote branches)
You have a similar notion with Mercurial with bookmark branches (which can be pushed/pulled).
Note that in Git, the data won’t “vanish” because there is no reference: you still have the reflog to retrieve those unreferenced commits.
The idea is to separate what has changed (the commits) from whym ie from the context of the change (the name of the branch).
Since you can fast-forward merge a branch, commits from one branch can be part of another at any time.
That is why Jakub Narębski questioned the design of Mercurial “named branches” (with branch names embedded in changeset metadata), especially with a global namespace, not very suited for a distributed version control system.
You create a branch to isolate a development effort (see “When should you branch?“), but with a DVCS, that development effort (the set of commits) should be published under any branch name. What local context (branch name) you have defined might not be valid once published to another Git repo.