I have been using Git for the past week or so, enough to get a good handle on its benefits and disadvantages.

I moved to Git from Subversion, after having done a stint of almost 6 years of using Subversion. A stint which also included doing some development on Subversion.

Despite appearances, I actually took a fairly structured (and long running) approach to learning Git, I got a book and read it, I played around with it, and I mostly dismissed it as “it isn’t solving my problem” and “I already know how source control works”.

Last week I had the chance to pick Aaron Jensen mind about Git, and he was able to clear up some conceptual issues about how Git operates. I made a bigger effort since to learn how I can make better use of Git and I think that I now know enough to be able to talk about it.

First, let me talk about Subversion a little bit. As I said, I am a long time user of Subversion, and I consider it an excellent source control system. It is, however, strongly aimed at meeting corporate development scenarios.

What do I mean by that? In Subversion, you have the root repository, and everything else falls out from there. That doesn’t sounds like such a problem, until you realize that except for your local working copy, every single operation is a remote operation.

Just to give you an idea why this is a problem, looking up a history of changes (including file diffs) is a real pain in Subversion. Merging (the actual act, not keeping track of it) is a pretty long operation as well.

That was the final deal breaker for me. I feel insulted whenever I have to wait for the machine, it should be the other way around, damn it!

But there are other issues with Subversion usage, specifically, for Open Source projects I don’t believe that the centralized model works anymore.

Consider the workflow for getting a patch in Rhino Mocks. You get the code, make the patch, send the patch. In the meantime, the project is moving ahead and you are forced to keep up with what is basically a dirty and unversioned working copy.

Worse, for me, when you send me the patch, it has to go back to the server for any old versions (slow! slow! slow!) and make me do a lot of the work.

Having a single source of truth is important, for official releases. But in the meantime, I like the idea of having multiple disparate copies that people are working on independently. They should.

Some other important thoughts, with absolutely no order:

Local history is another major important aspect. I mentioned that this is something that I sometimes do, and it is a total pain to go through that with Subversion, and it totally painless to do so with Git. I have TortoiseGit installed specifically for that, so I get a UI that I am very familiar with but with no network round tripping time.

I am not sure how to qualify this point, but it feels like Git is faster even when it does goes on the network. Project checkouts and remote commits seems to be faster. Even though on the face of it Subversion should be much faster at least for checkouts (Git gets the entire history, Subversion gets a single revision).

People keep mentioning having private commits as an advantage. I guess I see the point, but I am not sold on that yet. Sure, it is fun to be able to do that, but this is a paper advantage so far. What I really do like is that commits are fast. Which means that in many cases I can commit & push on the background while resuming work.

Github is another consideration, its major advantage is that it is taking care of a lot of details related to actually managing git.

For open source work, I love looking at this:

This gives me a good indication about the actual interest in a project.

Other things, like pull requests and their management makes me tingle all over, since they represent how people actually work in OSS project in real life and this represent a significant time saving.

There are other stuff as well, having a download button in the site means that I don’t get questions from people that have no Subversion tools or are behind firewalls.

Github is also a huge disadvantage since in less than a week I caught it broken at least twice. There are some things that I want to be stable, the place where I put my source code is one of them, and I don’t care if the unstable parts aren’t the Git repositories. As far as I am concerned, unstable site equals to nervousness on my part.

Anyway, those are my reasons for moving to Git. The tooling are pretty good, I got used to the git command line, gitk and git gui fairly quickly.

Comments

Just curious, "Why not Mercurial?" I've found its Windows support is better than git and seems to be easier to use. Bitbucket seems comparable to Github (but I haven't really evaluated them extensively).

Git is so very good at merging that you can actually embrace branches as a way to build out features (they're called "Topic Branches"). This type of development may seem extreme and weird for those coming off SVN - but you have to break your brain and stop comparing the two.

You can also break off a 3rd and 4th branch and merge them seamlessly back in - even if you forward the master branch with a bug fix - Git is smart enough to merge things together with a 3-way commit (easiest). If that doesn't work, you can actually tell it to merge using a different algorithm entirely.

And Git is lightyears faster - you're very right. This is because of the way Git stores the info. It doesn't store changes - it stores snapshots and pointers - much faster (especially when working branches).

I've been using Git for a year now, and enjoy it's speed and distributedness. I haven't yet read a book, which puts me squarely in the novice category on the Drayfus scale, can you recommend a good git book?

I just learning git also, and I've read about the feature branches that Rob mentioned. Still not sure that seems practical but I haven't had the need yet. I have to say git is really good at merging, but the rare time I ran into need to manually merge I was a bit lost. Guess I was a little dependent on using TortoiseSVN for right-click cruches.

Sorry you failed to find people who couldn't discuss hg like you wanted... the .NET community does seem to favor Git more than Mercurial (which I still do not understand; perhaps ruby influences; Mercurial is the better of the two in Windows)

One minor correction in your post though:

"Having a single source of truth is important, for official releases."

You still do have this. It is just in the form of a hash instead of a url. Even stronger you can define the main central repository as the one that is acknowledged to be run by the person the community considers as in charge of it.

Would you mind expanding on "Mercurial is the better of the two in Windows"? That's quite a strong statement with no supporting evidence. I've had very few issues with git in Windows.

I'll happily admit I've never tried hg, but I'll also admit I've never seen a compelling argument for hg over git. So why git? Git has github and it's quite a bit more popular as you said in .NET and Ruby communities.

Github is a boon for open source projects as many have exclaimed. I've never tried any of the hg hosting sites so please let me know if there are more potent sites for hg and there's something we're missing.

Just had a look at bitbucket, looks neat, probably similar in features to github. Perhaps another hddvd vs bluray? :) Git has more momentum/popularity it seems, but for those of you new, why not try'em both and make up your own mind...

Absolutely it is the same as hddvd vs bluray. Git has more momentum within .NET, ruby and C developers but Mercurial has a more active user list and irc channel.

@Aaron:

Though Git now has a couple of windows gui tools now, they still are not as functional or featured as TortoiseHg:

a. Git-Gui opens into an infinite loop of opening a modal window on my system in any repository which has "unstaged changes".

b. While Git seems to work from a command prompt (well technically I use a powershell prompt), everything I have read seems to indicate you are supposed to use either Cygwin bash or the included Git-bash prompt; Cygwin is a big turn off for me and Git-bash simply doesn't fit in to the rest of my environment (and I have yet to figure out how to run powershell scripts from it).

c. The basic git install doesn't even come with Gitk (at least it didn't when I last installed it at version 1.6.2).

d. I don't see any way to serve a repository from my local machine via Git-gui (if I could ever get past the infinite popup loop).

Mercurial treats Windows support as a first class citizen as opposed to an afterthought. Git is built on a Unix toolchain and thus requires portions of that set or ports of it (which is why it uses Cygwin or MinGW). Although MinGW is better than Cygwin, it is still not something I would prefer to have to deal with on my system.

Although the staging area in Git has more features than shelving does in Mercurial (and the shelve extension in Git combined with its staging area has more features than my Attic extesnsion), I find the way Mercurial does it to be more intuitive (disclaimer: I am obviously biased as I am the primary author of the Attic extension).

TortoiseHg has working 64bit integration with Windows (I have failed to get git-cheetah to work in either win32 or 64; but that probably has to do with me not having something correctly installed at the MinGW/Cygwin level) in its default installer.

Git-bash runs within cmd by default. Yeah I know this one is strawman but I really hate cmd.exe. Console2 isn't much better though (why isn't there a good windows terminal like the one in kde). At least Console2 is useable.

Granted the differences nowadays are very subjective. I still feel confident that Mercurial is superior (if even only slightly). Both are great for development and are superior than Bazaar and than any centralized system (don't get me wrong there though either, Bzr is even still good).

On Linux, I would say the two systems are equivilant. Mercurial can push and pull Git repositories (with the hg-git plugin) and TortoiseHg has Gnome integration, but git is still slightly faster in some cases. Subjectively I like the Mercurial command line better.

As far as bitbucket vs github... they are very similar. The differences that I notice between them:

github network graph <- really cool to be able to see what others are working on while you look at one repository (I wish bb has this; jespern is probably working on it)

github graphs <- interesting novelties

bitbucket versioned wiki <- for maintaining the wiki, this is really nice. It also helps if you ship the documentation because it can be parsed by docutils (I wish github has this)

bitbucket patch queues <- mq integration in bitbucket (equivilant would be guilt integration in github); interesting collaborative feature but I prefer just using forks when receiving contributions for my projects

With bb if you want to keep up to date with a source tree and all of its collaborations you have to follow each fork whereas github gives you that information directly in its network graph.

1a. not sure what you're talking about here, git gui works fine for me aside from the occasional hang

1b. Yea, I read that too, but it's FUD as far as I'm concerned, I use git from PSH as well.

1c. msysgit does and always has come with gitk (since a year ago when I first used it)

1d. I don't see this as git gui's place. I've never even considered serving a repository from my own machine remotely, that's what github is for. That said, there's probably a daemon somewhere but eh.

To each his own. I'd rather not deal with python on my system ;) Just kidding, but really, now that msysgit works out of the box this isn't really a valid argument--at least no more valid than "i just dont like it"

After briefly scanning the AtticExtension docs, it seems like attic/shelving is essentially topic branching? I've never used git shelf either, it seems like a poor man's branching. Branching works just fine in git so I don't really see any reason for this? Pardon my naivete...

TortoiseHg, if it is as far along as you make it seem does seem compelling for those that prefer the tortoise paradigm. I can't stand it personally so it's a non-issue for me.

You said it, strawman. msysgit also ships with Rxvt but my understanding is it's not up to snuff yet. No reason you can't switch git bash to console2 that I know of.

About gh vs bb, interesting comparison. Only question I have is about the versioning, github has a versioned wiki and it has pages (which is versioned in your repo) so I'm not sure what you're referring to? Does bitbucket version the wiki in hg? Also, github has the fork queue and supports pull requests so I'm not sure I see the value in guilt, but I've never used it or quilt.

The one problem I have with SVN is that when I want to look back into the history of a file, I always want to look back for a history of a part of a file, through blame, and want to see what was there BEFORE the last revision. The tools available don't show me that. Typical scenario: you release a bugfix for something, months pass, and someone comes up with an edge case which is affected by the bugfix, you want to look back what was changed at that spot, this isn't doable as blame doesn't offer you to browse back dynamically, you've to remember the revision and do this manually.

WHen I look at what Mercurial offers, especially on windows with both command line and tortoisehg, I can see what I miss. Tortoisehg is generations ahead of anything available for SVN and also for Git. I also don't really understand the hype about Git, as Mercurial offers the same package with better mature tools.

And tools is what's this is all about: SCM isn't a lonely system, it's integrated with other tools like bugtrackers / issue management systems. E.g. we use Trac internally with SVN. It works great because you can plan issues/ tasks ahead, check in code into svn with markers which hook the revision to the issues/tasks, so you can look back through trac which code was changed for that particular task/issue.

For OSS it might be less of an issue because sites like github and sourceforge offer these kind of services as well, but for development on projects outside OSS, it's essential that there's integration with bugtrackers/issue management systems, otherwise you end up spending lots of time tracking down changes in multiple systems which is silly.

As a last note, I have to say that, Aaron Jenson, you're a pain in the *** with your Yakunin style discussion technique. Bill honestly gave an answer and you bash him to pieces. Shall I file that under the typical 'linux-zealot' bickery or did you just have a bad day?

Frans, thanks for redacting, I was a bit confused... btw, never heard of Yakunin style discussion techniques, curious what that means, but I do know what a pain in the *** is.

Stephen, if you'd care to point out the BS in any of my arguments I'd be happy to clarify or shut up and apologize.

When you're dealing with two things that are so similar a slight change of perception or experience can alter the arguments for a particular side. I was simply responding to each point given my perception and experience.

How very odd Bill. That would surely sour me on git as well as I use git gui every day :) I assume you've tried a reinstall? What version are you running? Tried the latest? Does it do this in every repo?

It happens eventually with every repo; I've tried 3 different versions but not the latest (I stopped watching for updates with 1.6.2). I still use git from the command line occasionally, just not with any of the windows tools. I'll try the latest later today I think.

This issue and the fact that I couldn't get cheetah to work (or any tortoise-like git app) are what made me decide to stop evaluating git for my company's repositories when we migrated from svn.

Note that even with these issues, I would still recommend Git over svn (though I would rather people evaluate both Mercurial and Git for a week or two and I believe that most people coming from svn would favor Mercurial). Local history and the speed are simply game changers.

@Bill Barry: I'm not so advanced with Git, but I managed to get Git 1.6.4.2 to work on Windows Server 2008 x86, including Git-Cheetah and Tortoise-Git. If you have some free time, I can try to replicate your steps in setting up the Git environment, so you can pin point the problem.

@Aaron Jensen, the BS was that it was all "imo".. its meaningless when its clear you both like different things, theres no way his arguments were going to be a 'ah your right!' could only always have been.. I disagree.

Nobody here wins, who to listen to.. might as well go and try the technology yourself, and from what I can see for even HERE, mercurial is more what people want.

I use git from rxvt (and Console2) on Windows, though I'd prefer to use it from PowerShell. The ONLY reason I don't use it in PowerShell is I miss the color output support.

For example, when running git diff (force color output with git diff --color), I see all of the output with the color encoding in it (i.e. things like [ESC[1mdiffESC[m). I think some of the git commands in msysgit support color output, but not all of them do. If there is a way to get color output from these commands, though, I would be happy to be corrected!

Happy to announce that I have the latest git running and it seems to be working properly.

@David:

MS terminals (CMD, PowerShell) do not process ANSI sequences anymore (they stopped doing so in win98)[1]. This is unfortunate as it seems that it wouldn't be very difficult to actually do so. Instead with windows you have to write an interpreter yourself which parses the incoming text stream and calls the console APIs. I do not think it would be very difficult to write a general purpose script for PowerShell which would do this by intercepting the output and processing it before putting it back out[2].

I didn't see this mentioned in the article or the comments with people talking about Windows compatibility with regards to Git.

There is a project called GitSharp which is working to translate JGit to C#. They are a nice ways done and it includes a Git library for developing plugins and tools for Git in .NET but also includes a .NET command line interface for Git as well.

Agreed regarding using a visual diff tool, particularly if the changes are even remotely significant. I just like using the command line diff to get a quick feel for what happened in a commit.

I did find a way to get around it though! If you set your color.diff to always (instead of auto) in the .gitconfig file and also set your core.pager to cat (the default is less), you'll get color! Apparently the version of less.exe that ships with msysgit is the msys one which doesn't support ANSI encoding. I don't really need the paging support, so just pushing the output directly to the console works just fine. Note that setting color.status to always gives you a nicer color output on the git status command, too.