Mercurial & Git

About two weeks ago, I wrote about my thoughts on Mercurial and how I was switching to it from Darcs.

At the time, I had skipped Git because of its lack of Windows support. I have some contributors to pieces of Free Software that I write that use Windows, and that seemed a pretty big flaw.

But I recently discovered git-svn and git-svnimport, both of which look like great tools for working with our friends using svn that haven’t yet gotten ahold of the DVCS light. Then I noticed that Git has a CVS server emulation tool, which means that Windows users can use TortoiseCVS to interact with it. Nice.

I spent some time today learning Git. This was a lot easier having already learned Mercurial. Git and Mercurial have very similar philosophies to a number of things, but the Mercurial documentation explains all this far better than the Git documentation does.

I’m going to have to try both of them out more and see what I think. But git-svn (which is bi-directional) certainly looks like a very nice thing.

Neither of them have something as nice as darcs send, though.

6 thoughts on “Mercurial & Git

  1. Git has a MinGW port.

    Also, what does darcs send do that git-format-patch and git-send-email don’t?

    (You might also find git-imap-send useful if you have an IMAP server.)

  2. Nice to see people playing with git-cvsserver ;-) What does darcs send do and why is it so nice?

    If it formats a commit and sends it to upstream, maybe git-format-patch and git-send-email are what you are after?

    (will this cc me on your reply?)

    1. Well, the difference between darcs send and git-format-patch is, that the former maintains the commit identity, while the later simply creates patches.

      The idea in git is the logical steps and not how the work was done that should be tracked. So the contributor prepares the changes, against a whatever version, refactors them into logical steps (using stgit or patchy-git git add-on) and sends them in with git-send-email. And the maintainer will apply them to his current head, so they most likely end up with different parent and therefore slightly different anyway. Git has separate ‘author’ and ‘committer’ fields to keep track of who sent it and who applied it.

      It should not be too hard to create a git command that would send whole commits though. Just find what a push would do and add it to a pack object instead.

    2. The nice thing about darcs send is that it looks at the remote repository, compares it to the local, and *automatically* sends the patches that local has but remote doesn’t.

      But it doesn’t just send a diff, it sends the exact changeset, which, when applied remotely, will have the same hash as locally. So there is no merging later unless it is modified before applying.

  3. Good point. There are good reasons for the hash being different — the hash reflechts a tree identity, and a particular history.

    However, in the subsequent merge (at _your_ end), if the patch you mailed out was applied without conflicts, then git will recognise that and not show a merge.

    OTOH, it will show a conflict if your upstream edited the patch. This identification is done by hashing the diff so if someone else sent the exact same patch, git will recognise it as merged in too.

    So, GIT does deal with “patch identities” creating a SHA1 of the unified diff — but it treats those as peripheral. The _central_ concept is the content of the tree. From my experience with patch-centered SCMs (darcs, tla), tree identities win big time because it’s cheap to generate patch identities — whereas it’s a lot more expensive, complicated and failure-prone to generate full trees from series of patches. (When I write failure-prone, I’m thinking of tla…)

    Hope that helps!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.