The worst part about Git is the "Git-SVN Crash Course" tutorial, because it will convince a newcomer that their understanding of how source control works transfers smoothly to Git. If you combine that with the fact that most smart people simply refuse to read documentation and will just mash on the keyboard until it appears to work, it means that teams who are starting out using Git are on the yellow brick road to a world of hurt.

Git follows Linux's philosophy of refusing to protect you from yourself. Much like Linux, Git will sit back and watch you fuck your shit right up, and then laugh at you as you try to get your world back to a state where up is up and down is down. As far as source control goes, not a lot of people are used to this kind of free love.

Milo has been using Git from the get-go, and the git pull/git push with a central repository works well enough when you only have a handful of developers.

This fits with the Subversion worldview that a benevolent central server will never lead you astray. The first time you get some error about not being able to push non-fast-forward commits to origin, you kind of gloss over it, and a git pull fixes you right up. If you understand Git as you understand SVN, you can easily mistake this error for something like "oh, I just have to do a merge because someone else's commits beat me to it". Well, technically that's right, but for the wrong reasons. Using this model, if you think of the developers as different threads sharing the origin repository resource, Git is putting lock on the whole repository, as opposed to individual files. With a lot of threads sharing a coarsely-locked resource, there's always going to be contention. However, in a small enough team, it's workable to think of it this way.

This is where smart people run into trouble. We know in the backs of our minds that something is just a little off about that non-fast-forward-commit error message, but everything looks fine, so why go read about what's going on? I am generally not a fan of reading documentation until I am debugging a problem, because I expect software to behave as it would if I wrote it. Good documentation is condescendingly terse, and Git's documentation is like an art critic who giggles at you. (The description of git-rebase is "Forward-port local commits to the updated upstream head". Oh, fuck off.)

In the last couple of weeks, we started using Gerrit for code reviews, and anyone who was using Git like a translation table for SVN commands just heard the bell ring at the School of Hard Knocks.

Gerrit acts as an intermediary between developers and the origin repository. You send commits to Gerrit and it holds them in purgatory until they are signed off on by another developer. Then, if the commit applies cleanly to the branch, Gerrit applies it. Otherwise, it asks you to upload a merge commit, which is where the fun really starts.

The upside to this system is that it prevents other peoples' git-fuckups from becoming your git-fuckups. The downside is that because commits are held in this transient state, it's very easy to lay a path of destruction through your local repository with rebase and merge if you don't completely grok what's going on. Like old skid marks on a highway, our codebase is peppered with merge commits and cherry-picks that are the only living records of a series of oh-shit moments.

The problem isn't that Git is to hard, it's that smart developers are impatient and have exactly zero tolerance for unexpected behavior in their tools. While Git is the trendy thing right now, perhaps some day you will come across a grizzled developer who is using SVN, and when you ask him why, his answer won't make sense, because it's a Zen thing.