Git vs Mercurial branches

Martin Geisler martin at geisler.net
Tue Mar 10 17:00:26 CDT 2015


Avner Silberman <avner at avvi.org> writes:

> One example I came across from this quote in the Workflows
> <http://mercurial.selenic.com/wiki/Workflows?highlight=%28git%29%7C%28history%29>
> page on selenic.com
>
> "Note: The difference between Mercurial named branches and git
> branches is that git branches don’t stay in history. They don’t allow
> you to find out later in which branch a certain commit was added."
>
> This strikes me as an important piece of information to lose. Can
> someone inform if this is a valid statement, and what you view is on
> the importance of preserving this information?

It remains true, assuming that the branch is later deleted. However,
even if deleted, you can often find the old branch name in the merge
commit, since the default commit message for a merge will include it.

In my view, the biggest difference between the two kinds of branches is
the ability in Git to forcibly update a branch. This allows me to
*re-publish* history, which I find extremely useful.

A standard workflow with Git is to push code to a shared server, open a
pull request, get review feedback, and then iterate on the code. When
everybody is happy, the branch is merged. In Git, you can do

  git push -f origin my-branch

after modifying commits on my-branch locally. This will send the new
commits to the server and *move* the branch pointer on the server. The
pull request will automatically update (I'm primarily basing this on
GitHub's behavior, but I believe other Git interfaces will do the same).
This is what allows you to publish history sooner rather than later: you
get to correct your mistakes before they are merged into the master
branch.

With Mercurial and BitBucket, you'll work differently: when you get
review feedback on your pull request, you address the comments by adding
more commits to the branch. These commits can fix bugs you made in
earlier commits. They cannot fix bigger problems in the earlier commits,
such as a commit doing something else than what the commit message says
(message says "fixed issue 123", but the commit also did some unrelated
refactoring).

If all you care about is the diff between the first and last commit on
your branch, then this approach is just fine -- it even preserves the
bugfixes made to the not-yet-merged code. However, if you care about
presenting a neat history, you will have trouble doing that with
Mercurial and BitBucket.

This is the single biggest change in my workflow after I started using
Git and to me, it's a very important change. I see this and *the* single
feature that enable pull requests to work so well with Git and, frankly,
quite poorly with Mercurial. After pull requests became a widely used
way of collaborating, this became a killer feature for Git.


The above is set to change with newer versions of Mercurial as the
changeset evolution[1] features become more mainstream. Changeset
evolution will allow you to change your mind too: you can modify a
commit locally and re-push it to the server. The server will then hide
the old version of the commit.

This promises to solve the "republish my work" scenario plus many more
complex scenarios that Git doesn't consider at all.

[1]: http://mercurial.selenic.com/wiki/ChangesetEvolution

-- 
Martin Geisler

http://google.com/+MartinGeisler
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 818 bytes
Desc: not available
URL: <http://selenic.com/pipermail/mercurial/attachments/20150310/46853b60/attachment.pgp>


More information about the Mercurial mailing list