Caffeinated Simpleton

Fine. Git is Awesome.

I’ve been a big fan of Mercurial for a while now. Harmonize is all kept in Mercurial, and most of my side projects are as well. Mercurial is great for a number of reasons. It’s easy to use, not only for former subversion users, but also at a conceptual level. Understanding how DVCSs work is easy when you’re using Mercurial. The vocabulary is sparse and makes a lot of sense. As added bonuses, it runs on Windows just as well as it runs on every other OS, and it’s written in Python (my favorite language).

However, I’ve decided to allow git into the very exclusive club of version control systems that don’t suck. Git makes two, and it might become my favorite as I get more comfortable with it.

To pause for a moment, one of the things git does not do better is github. Github has, perhaps, a slight advantage over bitbucket because of the size of the user base, but that doesn’t make it inherently better. It’s just a better social experience for now. From what I can tell, bitbucket matches github feature for feature and outdoes it in some areas. I’m a huge fan.

That being said, there are a few things git does better than mercurial. The first is editing commit histories. Mercurial supports a similar feature through extensions, but git has a leg up by coming with the ability to alter any part of your commit history built in. This allows things like cherry picking, merging batches of commits into one, and cleaning up commit logs. Mercurial can kind of do these things, but it’s much better supported in git. Plus, as a relative newcomer to git, I’m sure I haven’t even scratched the surface of what’s possible.

The second advantage that goes to git is local branching. Now let’s be clear here. Mercurial does support branching in much the same way git does. However, if you ever push to a remote repository, your branches must exist there or you must create them there. Local branches are nice because they don’t need to clutter up whatever master repository you have. You can have your own branches for whatever you’re up to and don’t need to mess with what the rest of the world is doing. I use this all the time and love it.

In the end though, there is one feature that has pulled me toward git and kept me there, and that’s git-svn. My current employer uses Subversion, and since that is not one of the version control systems that don’t suck, I quickly became agitated. I desperately tried to use Mercurial with SVN, to no avail. There is pretty good support for mirroring a SVN repository in Mercurial, but pushing back to svn quickly became a nightmare. I even found a script that did a pretty good job, but in the end, the support wasn’t there.

Git-svn, however, is a different story. It utilizes git’s amazing ability to manipulate commit histories to allow you to pull down changes from an SVN server, do your own thing, commit as much as you want in yout git repository, and then when you’re ready, push it all back to the SVN server. It’s incredible. I can do all the local branching I want, play with things, finalize a feature, whatever, and in the master branch keep up with the day to day bug fixes. When I’m ready, I just merge and push. Now I don’t even think about dealing with straight SVN. The first thing I do if I’m going to be doing anything beyond reading code is pull it into a fresh git repository. From there, I’m free to use version control as it should be used without bothering anybody else. At the end of the day, I can either push all my commits out, or modify them into a few larger, more well defined commits. I pretty much never fight with subversion anymore, and that makes me a happier person.

Despite what I’ve said here, I still love Mercurial. It’s such a simple and well designed piece of software that it makes me smile a bit. It’s like the Mac where git is like Linux. I work on Linux because I need the raw power, but at the end of the day, I really want a mac to be sitting there beside me. So make your own decisions, but at this point I’m willing to admit it. Git is awesome.

Tags: , , ,

This entry was posted on Saturday, January 31st, 2009 at 4:29 am and is filed under Development. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

  • Anonymous
    check out gitserve to emulate hg serve
  • Mr. Anonymous, your da bomb.
  • Wm Tanksley
    As a committed Mercurial user and fan, I have to admit: well said. Git does many things better. Right at the moment Mercurial is better on Windows, so any cross-platform project needs to carefully weigh the options, but I find Git's current feature set to be more capable.

    Also notable... Although Mercurial's historical refusal to deeply support history rewriting is well-principled and reasonable, Git's support for it is actually sensible given Git's architecture. It turns out that while Mercurial is built on the idea that a version control system should remember differences (and reconstruct the actual files), Git is built on the idea that a version control system should only remember files (and store differences only to save space). Thus, when you edit a Mercurial history you're forcing Mercurial to alter the most important data it has; when you edit a Git history you're merely changing some files (usually only removing files), no different (in principle) from checking in a branch.

    Mercurial's architecture makes perfect sense, and gives it a huge head start in speed and size; but Git's architecture really does preserve the things that matter most (the actual files), which makes inherently risky things like rewriting history relatively risk-free.

    Thumbs up to Git for a flexible and sensible architecture.

    I'm still using Mercurial for its superb Windows support (sorry, guys, gotta use it); but I'm keeping my eye on Git. (By the way, aside from extreme slowness, Git also hasn't gotten git-svn working reliably on Windows -- at least not while I've been watching.)
  • smith
    mercurial (as of 1.1) does have local branches too http://www.selenic.com/mercurial/wiki/index.cgi...
  • Good post, but I'd like to point out that Bitbucket has no in-place editing / committing nor a Network Graph for seeing activity among forks. These are two of GitHub's most important features, so I think the "matches feature for feature" bit may not be entirely accurate.

    For instance: http://github.com/mojombo/jekyll/network

    Bitbucket also does not have commit commenting, another huge GitHub feature.

    As you say though, Bitbucket does have features GitHub lacks (like the hg-powered wiki - GitHub's is not git powered) and issue tracker. The two sites take different approaches to patch management as well (patch queue vs fork queue).

    Both sites have many similar features but it's unfair to call them equivalent as each has useful, unique features the other lacks.
  • These features are absent. You are right. But at the end of the day, forks and pull requests are the truely important features of github/bitbucket.

    I can live without the other stuff though they would be nice.

    In place editing/committing is something I would probably never ever ever do. I like to test that a change works before commiting it. Maybe for documentation it would be ok, though lots of documentation is generated and you would probably want to make sure it looks the way you want it to before committing.
  • Perhaps I was a bit too abrupt. I understand that they both have unique features that draws some distinction between the two, but bitbucket and github are close enough (in my mind) to make the existence of a central place for people to coordinate on code a non-issue in choosing between the two.

    I think it would be pretty cool if they could merge and allow you to choose between using hg or git for a project. That would help the social aspects without (hopefully) hurting any of the technical ones.
  • And at the end of the day, you are stuck with a closed source infrastructure like github that can kick you out the way they want. Github is nice, but you lose the principle of a distributed system by just putting everything in the same bucket. How sad... I am working on InDefero http://www.indefero.net to avoid that, I can use Mercurial and Git and stay independent from those services we don't know if they are going to be here tomorrow.
  • I'm not sure I agree with you there. You don't really lose anything by using github and instead just gain their very cool features. If github bites the dust tomorrow, you still have all your cloned repos in tact on your own machine, you'll just have a much harder time coordinating with other people on the project.
  • This is the problem, you are locking yourself into a system for your code development where you depend on the good will/good health of a company. All your workflow you have slowly developed over the time is then lost, this is really a big blow for a project. Basically you still have the code, sure, but everything around can be lost from one day to another. Don't tell me, these one are good, they will not do that, etc. because just count the number of "cool companies" which failed or were bought back by a bigger one and then screw up everything. When you do go with a closed source service provider, you need to take that into account, if not, you cannot come later and say "If I knew..."
  • I love git, and the fact that it's blessed by Linus means it's not going anywhere anytime soon. In fact, I'd put money on the fact that git will become the defacto standard in VCS.
  • What about its lack of enthusiastic support for Windows? That's going to have to change for it to be the de facto standard.
  • Cygwin doesn't count :).
  • Boffo
    msysgit is the native (non-cygwin) port. And it's quite usable.
  • msys is a smaller version of cygwin. They're both POSIX compatibility layers, and as such, I really don't like depending on them.
  • Wm Tanksley
    That's not entirely accurate... msys is a set of libraries to allow POSIX applications to (sometimes) run on Windows. Its entire intent was to get rid of the "compatibility layer" problem with cygwin.

    I'm not saying you SHOULD be using msys or git; but I am saying that using it is no worse than using any other large, multiplatform library. Certainly Qt would be no better, for example.

    There are better reasons; for example, one might dislike the atrociously slow performance of git on Windows after seeing so many people advertise its speed as being one of its best features. Perhaps one might dislike its slapdash implementation in an odd mixture of bash, perl, and C. (And probably others.) I would share those dislikes.
  • Tom
    its also purely command line with a bash-like shell. How many windows developers have you actually worked with? they want their tortoise or vs integration not some hacky cli tool.
  • I don't care if git makes it to Windows or not, personally. I think it will, but really, it was developed by filesystem designers for distributed version control of the Linux kernel, so the focus is on Linux boxen. That's where the standard will emerge. Windows will probably do its own thing.
  • Have you seen tortoise HG, its an awesome piece of software. Although I hate something called windows, some of the people I associate with use it (I am going to have to drop these people soon though :) and I got them to love mercurial because of tortoise HG.

    Now I hear they are working on the mercurial version soon though.
  • EDIT: s/mercurial version/ git version/
  • Andy
    I have a very similar story.

    I switched to git for git-svn until hgsubversion came out and originally I did not like git much either. I like the mercurial documentation and philosophy. Git grew on me a lot for exactly the reasons listed: extremely cheap local branching and ability to edit history. The bookmarks extension is touted as enabling git-style branches, but I haven't found it to work that way in practice at all.

    Editing history in mercurial drove me to learn mercurial queues, and now I'm totally addicted to patch queues. mq is also very polished and is a joy to use. It's actually the only thing that keeps me on mercurial. I've looked into patch queues for git, but none of the implementations suit me. StGit makes the index unusable and TopGit is to heavyweight for my development workflow (it's more built for package and patch maintainers). I like the semantics of Guilt (especially the interaction with branching) but it's kinda busted on macs, as all the development has been done on linux machines.
  • Tim MacEachern
    I'm using hgsvn for Mercurial/Subversion work. Create the combo SVN/Mercurial repository using hgimportsvn/hgpullsvn. Then clone a working Mercurial repository from that, using patches (hg qinit, qnew, etc.) for your work. The working repository can be updated by popping your patches, doing a pull, then repushing your patches. The hgsvn docs I've seen don't say how to push back work. I do that by starting a patch queue on the combo repository as well (hg qinit), then apply the work patch to the combo using this sequence:
    hgpullsvn (check for and get any updates from the main SVN repository first)
    hg qimport ../path/to/your/patch/patchname.patch
    hg qpush
    svn stat (make sure you like what you see)
    svn commit
    hg qpop
    svn revert -R . (remove the patch effects so you can do hgpullsvn again)
    hgpullsvn (refresh the combo svn/hg repository)
    hg qdelete patchname.patch

    Then, on to your working repository, do:
    hg qpop -a
    hg pull -u
    hg qdelete patchname.patch
    hg qpush -a
  • I tried to do this for a while, but it's a giant pain. git-svn is way easier, though from what I hear, hgsubversion might do the same for Mercurial.
  • segv
    Have you ever tried hgsubversion? It works similar to git-svn and is just awesome. you can also have local branching using the Bookmark extension in Mercurial 1.1 or later which gives you nearly the same power as git branches for local stuff.
  • Larry Hastings
    IIUC, Mercurial added support for git-style local branches just recently, in version 1.1. Mercurial calls them "bookmarks".
  • I am not quite sure this is correct. I believe git-style local branches don't automatically get pushed, whereas Mercurial's do unless you're careful. We're currently looking into having such truly local-only local branches in Mercurial which you'd have to explicitly push/pull.
  • While with big repos this is a bit of a pain, mercurial local branches can accomplished by simply cloning locally.

    hg clone . ../my_local_branch
  • Wow! That's pretty great. All these advantages that go to git are quickly fading away.
  • If you like hg, take a look at hgsubversion - it aims to do much the same thing as git-svn while letting you stay in hg.
  • HgSubversion looks pretty cool. I'm excited!

    I had tried hgsvn, which didn't really support pushing. It looks like this isn't quite ready for production use, but I'll be keeping an eye on it for when it is. This is definitely a big step for Mercurial.

    It looks like you're one of the contributors? If so, thanks a lot for working on this! This makes Mercurial that much better.
  • I had a similar experience. I still think git is cumbersome to use, but I do truly think it is better designed that mercurial. Using merqurial queues to do thinks the git way is to cumbersome. I think soon I will move to git. The only thing I will miss is "hg serve", I wish there was a quick way to do that with git cause I *HATE* gitk from the bottom of my heart.
  • gitk is ugly, but very powerfull and well designed, indeed. And nice alternatives exist in the GUI world (qgit, Giggle, ...)

    If you insist in doing it from a web browser, try git instaweb. It's probably more hacky than "hg serve" in the implementation, but it does work too.
  • I am not sure what you mean by well designed, I get lost in it everytime I open it. I don't only hate it cause its ugly, its altogether unusable. I'd rather have them spent the time developing something like hg serve.
  • gebi
    a short alias for your gitconfig:
    [alias]
    serve = !sh -c 'git daemon --reuseaddr --verbose \"$@\" --base-path=. --export-all ./.git' sh
  • Thats not exactly what I wanted. I completely forgot that hg serve is a way of casual sharing of the repo :). However, I meant "hg serve" in the sense of seeing changesets and looking at graphs and merges from the web.
  • I agree, hg serve is marvelous.

    I truly cannot pick which one I like more, but it took me a long time to get to the point where I could even admit that git was good. At first, its poor documentation and wretched user interface just completely turned me off. Having fixed that (mostly) and added support for SVN, I'm willing to admit that it's pretty good.
  • I do not know how I typed that, my English usually ain't that bad. :)
  • I haven't had a chance to use Mercurial quite yet, though your Mac analogy tempts me. I've been using git and github for some time now, and it's been a slick experience overall/ Like you said, quick local branching is probably one of the best features.

    That said, I'll give mercurial a try for my next side-project - always a good idea to at least try out new systems.
blog comments powered by Disqus