Still hatin’ on git: now with added Actual Reasons!

Monday’s little diatribe on git seemed to stir up quite a bit of strong opinion, both agreeing with me and disagreeing.  As is often the case, they two camps seem to be split about 50-50, which makes me happy.  It means I can be confident that I’m not talking complete arse-gravy, but I have a good chance of actually learning something.

For anyone who wasn’t around on Monday, the substance of my post was “git is bad because I don’t understand it”.  Or to paint myself in a slightly less bad light, “git is bad for me because it makes assumptions about how I work that don’t match how I actually work”.  Or, to summarise the summary, “git is the work of Sauron Gorthaur, the Abhorred, servant of Morgoth Bauglir, the Dark Lord that was called Melkor, destroyer and despiser, the corrupt Ainu and corrupter of Arda”.

I’ll admit that yesterday’s post was more a howl of anguish than a reasoned argument (although I still like the Harrier analogy).  Having now calmed down a little, I thought it might be worth explaining myself a bit more, and addressing some of the comments, both here and at Hacker News.

Explain yourself, Taylor!

First, I was a bit shocked at the number of people (mostly at HN) who seemed to think that my whole problem with git is the need to specify -a when doing a git commit of all changed files.  Folks, that was what is known as an example of how its model isn’t a good fit for how a lot of us work.  There are many more of these — for example, the fact that if you run git tag and subsequently push your repo, the tag doesn’t get pushed.

Here is a more serious problem that I run into all the time (including once this very day):

  • I make a one-line change to a single file.
  • I commit my change.
  • I git push, only to be told “! [rejected]     master -> master (non-fast forward)”.  (This is git’s cuddly way of telling you to do a pull first.)
  • I git pull, only to be told “CONFLICT (content): Merge conflict in filename.  Automatic merge failed; fix conflicts and then commit the result.”

So far, so good — someone else edited the same region of the same file as I did (among their other edits): of course its a conflict, there’s nothing git could do differently here but notify me and ask me to fix it.  So I edit the file, fix the trivial conflict, and git commit filename.

Nuh-uh.  “fatal: cannot do a partial commit during a merge.”

Well, darn.  So, OK, no problem, I already fixed the conflict, so now I’ll just git merge again to get it to make its world consistent, right?  Nope: “fatal: You have not concluded your merge. (MERGE_HEAD exists)”.  Well, duh!  I was telling you to merge, you stupid git.  You’re the branches-and-merges-are-easy version-control system around here.

All right, so I will just git pull again, and this time the merge will work OK.  Gotta work, yes?  No.  “You are in the middle of a conflicted merge.”  Well I knew that!  That’s why I am trying to resolve it.  In fact, that’s why I have resolved it!  All I am asking you to do is accept my resolution.  Please?  Is that so much to ask?

But wait — it’s worse than that!  Not only can I not commit the file that had the conflict: I can’t commit any other file.  My whole repo is stuffed until I satisfy the hungry god.

But wait — it’s worse than that!  git status shows that there are many, many modified files even though I know full well that I only edited the one line of the one file.  Because all the other changes that my colleague made have been splunged across my tree and suddenly, what the heck, they’re my responsibility!

The solution turns out to be that I have to use git commit -a, i.e. commit all my changes in one go.  But, dammit, git, that’s not what I wanted to do!  If I like to commit on a file-by-file basis, what business is it of yours to forbid me?  And: much, much worse: my commit -a re-commits all the changes my buddy had already made and commited!  Seriously, git: what the hell?

Something is rotten.

A handy household hint: how to abandon your changes when dealing with a conflicted merge

Of course, in the merge-conflict scenario above, you may sometimes see that your friend’s changes are correct and leave yours irrelevant, so that you just want to throw your own changes away and use the version you pulled.  Should be pretty simple, huh?  Well, according to the top-voted answer to this question on Stack Overflow, the correct thing to do is:

git reset –hard HEAD
git fetch origin
git reset –hard origin

Talk about intuitive.

Here’s another one that I hate.

I needed to get back an older version of a binary file, foobar.doc, so I could compare it with the current version and see what had changed. (git diff is no use in this situation, because it works on text: I needed to get hold of the earlier revision so I could pull it into OpenOffice, which knows how to compare documents.)

The command that does this is git show, which writes the old version on standard output so you can redirect it into the file of your choice. In general, the command is git show revision:pathToFile.  revision can be HEAD^ to mean “the one before the current one”.  But  when I did git show HEAD^:foobar.doc, I got back a more than usually incomprehensible error message.

fatal: ambiguous argument ‘HEAD^:foobar.doc’: unknown revision or path not in the working tree.

Use ‘–‘ to separate paths from revisions

It turns out that this is because the file in question isn’t at the top level of the git module: when I said pathToFile earlier, I really meant it — you have to give the whole path relative to the root of the module.  (The bit of the error message about using ‘–‘ turns out to be complete red herring.)  So I have to use git show HEAD^:dino/epub/foobar.doc, even though I am already in the directory dino/epub.

You can’t tell me that’s right.

What makes it much, much worse

I just know that someone — probably several someones — are going to reply to this article saying: “you are mistaken; git is correct.”  These people, most of them kindly and gently, will talk me through my misconceptions about what a version is, what a commit is, how it affects the index, what  a merge means, why it has to be this way and why I am sadly mistaken in thinking it should be otherwise.  If we were discussing this in a pub rather than over the Internet, they would probably find a scrap of paper and draw a nice state-transition diagram for me, showing how the various change-sets propagate between the various checkouts, branches, indexes and repositories.  Nine times out of the ten, this will be done with patience and tact, with a side of burning evangelistic fervour.

Here is my rebuttal:

I.  Do.  Not.  Care.

This is what I meant last time about git not degrading gracefully.  It’s great that it handles multiple local and remote branches and merges and all the other stuff, but you can’t Just Not Know about that stuff.  You start out believing what you’re told, that you can just use clone, pull, add, commit and push, and ignore the other 139 git commands(*).  But you can’t.  You have to keep learning more of them, and learning new and baroque ways of invoking them; and, more importantly, learning more of the concepts.  Any day now, I expect to learn that before git moves files into the index, it first keeps them in a top-secret pre-index stash-cache area.

(*) I am not exaggerating: /usr/local/git/libexec/git-core on my Mac contains 144 commands.  /usr/lib/git-core on my Ubuntu box is less promiscuous: it contains only 138 commands.

Who is the user around here?

Is it terribly old-fashioned of me to believe that when a user uses a tool, he should be the one who determines how it’s used?

The bottom line for me with git is that I am sick of being pushed around.  It swans about as though it owns the place.  It make arbitrary demands.  It tells me what to do.  It’s as though ext2fs insisted on particular file-naming conventions, or vi mandated a specific indentation regime for your C code.

Unless of course …

Unless git is a hammer and I am trying to use it as a screwdriver.  Or perhaps more appositely, it’s a bandsaw and I’m trying to use it as a bread-knife.  Or indeed, it’s a Harrier and I’m trying to use it as a bicycle.

Which I suspect is the case, and why I think the move back to CVS/Subversion might be the way to go.

Some responses to comments

But git does all these cool things!

I know it; and All These Cool Things are of course the main reason I sideways-graded to it in the first place.  In particular, the ability to commit (and do other things) when offline and not connected to the master repository is a huge win, and if I do grade back to CVS or Subversions I am really going to miss it.

So I’m not saying, or didn’t mean to say, that git doesn’t offer real advantages over CVS and its brethren.  I’m just saying that these things come at a cost; a significant cost, that git advocates are in a bad habit of greatly downplaying.  (Sometimes git advocates remind me of The Borg, or perhaps Moonies — they seem so earnest and so committed to what they’re doing, and so completely wired into their tribe’s way of thinking that they can seem unable to contemplate the possibility of any other way of thinking.)

But git has cheap branching

I know it; but I don’t want to branch.  To read a lot of the tutorials it seems like git people branch all the time just for the fun of it (and therefore merge all the time, too).  Sorry, don’t want to play that game.  Cheap branching is better than expensive branching, sure, but that’s like saying influenza is better than cancer.  I’d rather just not be ill at all, thanks.

Your mileage may vary, of course.  The point is that git doesn’t give you the choice.  Oh sure, it pretends it does (“just use clonepulladdcommit and push!”), but the truth is that branches lurk everywhere — in tags, for example — and you simply can’t Just Not Use Them.  That’s not a good model for how I want to work.

(Git Advocate: “That’s not a bug, it’s a feature!”  Sorry, not interested.)

But git lets you use any unique prefix of a commit ID, so you can use 23bbcf84 instead of 23bbcf847889c1fbfbb368b27e7b4ef3648879b1

And yet, I am unmoved.  Call me weird, but somehow I still prefer 1.8.

This should not need pointing out, but typing 40-character nonsense identifiers is only one of their many drawbacks. That I can abbreviate them to a prefix that might be unique enough mitigates the pain, but in no way eliminates it. Anyone can tell that 1.9 is later than 1.8. Who knows whether 745a4a4275c0322e5e699b02f8783b86ec14dc99 is later than bb7619b6568507d696516b1dd663b7b343d782f6?

There aren’t many sushi pictures in this article

Sorry, my bad.  Here you go:

Try Mercurial instead, it’s similar but has a great tutorial!

I might just do that.

Try Fossil/Bazaar/Darcs/Arch instead!

Sorry, not gonna happen.  The problem is that to try out a version control system, you have to trust a bunch of your code into it, and use the system to share that code across multiple computers.  In the DVCS world, git seems to be the most popular by a long way; Mercurial has a biggish following so might be workable, perhaps as a staging post on the way to learning to love git, but I just don’t have the time or energy to spend in learning half a dozen different systems.

But wait, Taylor!  “git seems to be the most popular by a long way” — is that any criterion to use in choosing something?  vi is more popular than Emacs; Windows is more popular than Linux; Britney Spears is more popular than Dar Williams; Big Brother is more popular than Veronica Mars.  Yet you will never find me hacking with vi on a Windows box while listening to Britney with Big Brother on in the background.  So why would I select a version-control system on that basis?

Simply because nine tenths of the point of version control is so that my colleagues and I can hack on the same code-base together.  And that requires that we all use the same repository, which has to be under a single, jointly agreed, VCS.  If I decide that Darcs is the answer for me, then I have to persuade all my friends to try the same experiment at the same time.  Not gonna happen.

In fact, I think I’ve probably just persuaded myself not to use Mercurial, either.  I might still read, though.

Try reading Insert name of git tutorial here!

Thanks for the link.  I may well do so.

You should read the Pro Git book

I probably will, thanks for the all the endorsements.

Git is not version control; it’s change control

I will ponder this. It seems profound.

(Although I notice that not all commenters seem agreed on whether it’s true.)

the biggest step is using git the way it’s intended: lots of branching, partial commits and rebase / merge to keep your downstream changes clean, etc.

Yeah, I know.  That’s exactly what I’m trying to avoid.

The conclusion of the matter

One of the more thought-provoking comments on the last article was this one from teh:

I disagree with “Git’s just version control. I resent the idea of investing a month of evenings and weekends just to be able to check my freakin’ files in.”.

Version control is not “just” version control, it’s a first class tool for every programmer, up there with recursion and all that jazz. A programmers work is transforming code from one state to another. Git treats these transformations as first class objects, allowing you to rewrite or reorder them, have alternative transformation branches, send them around etc.

I still, frankly, resent the idea of spending the amount of time that I know will be necessary to become a git wizard.  But I am increasingly reconciled to the idea that it will be time invested rather than time wasted.

I don’t intend to be graceful about this — I plan to mutter and groan and whine incessantly — but I have a horrible feeling the the outcome of this article and its predecessor is that I’m going to end up Deeply Learning git.  I don’t want to — I hate the idea of ending up as one of the Git Advocates that I was complaining about earlier — but I think I’m going to have to.  And if I do it, I’m going to do it properly, which means *sigh* another book, and probably another Long Overdue Serious Attempt At series.

As Xiong Chiamiov wrote in a comment:

I use it because the benefits outweigh all of the things that you mentioned.

Dammit all, he’s right, isn’t he?

Update 1 (a couple of hours later)

Very important point in a comment by Chris, which I should have made in the original article:

And at the risk of sounding absolutely trite, at the end of the day isn’t the important thing that we actually use some form of version/change/source control at all, implementation be damned? After all, isn’t that what separates us from the monkeys?

So, so, true.  From 1990 to 2000, I used SCCS, a version-control system written in 1972 that was so amazingly primitive that it still thought digital watches were a pretty neat idea.  It makes CVS look like the height of power and sophistication.  I am here to tell you that difference between not using version control and using SCCS was like the difference between night and day; after that, everything else is trivial in comparison.  Well, maybe not trivial, but the productivity gap from No Version Console to SCCS is much greater than the gap from SCCS to git.

Thanks for reminding me of that basic fact, Chris.

Update 2 (the next morning)

Many thanks to all of you who have commented (well, nearly all of you).  I think I’ve seen more genuinely helpful insights in the comments here and on the previous article than in any of the various git tutorials I’ve read.  In particular, I have learned the important concrete lesson than git commit -a is not my friend: an important lesson that should be taught to every git newcomer.

I don’t like to single out individual comments when so much useful stuff has been said (though I’ve also been called an idiot rather more times than I usually like), but for those of you who don’t usually read comments, please just take a look at this one from Kragen Javier Sitaker: apart from anything else, it contains by far the best justification I’ve ever seen for git rebase (or git lie, as I prefer to call it).

132 responses to “Still hatin’ on git: now with added Actual Reasons!

  1. Maybe it’s just that the needs of a huge highly-decentralized version/change control system like Linux are just so fundamentally *different* from small-(or even large-)scale centralized VC that You’re Using The Wrong Tool.

  2. I wasn’t in on the discussion from the previous article, but it sounds like git can do what you want if you just replace the use of pull with rebase.

    Also, given Linus’ opinion on CVS, I’m not certain that making it very hard to migrate to from CVS wasn’t on purpose.

  3. David Turnbull

    You’re correct in that git is not as easy to make tiny commits, but SCMs really should be valued by their ability to deal with really _complicated_ situations.

    Maybe you’ve forgotten how much time you probably spent figuring out how the goddamn hell to use cvs/svn in the first place (it’s been a decade or more for a lot of people, now).

  4. Darren Stephens

    “to become a git wizard”

    – who brought David Blaine inot this?

    (sorry, lame Marcus Brigstocke/Now Show joke)

  5. Derick Baily over at Los Techies blogged about using git with Subversion earlier this year:

    It’s about how to use local git branches even when you’re using a remote Subversion repository.

  6. @David: I think the whole point was UI design, the fact that Git reportedly fails miserably at this – making complex things possible is not excuse for not keeping simple things simple.

    Now adding my $0.2 to the discussion, I use both SVN and Mercurial, and as a programmer they were both very easy to pick up as I rely on Eclipse IDE plugins for 99% of the work. This includes some SVN projects with moderately complex branching and merging reqs – SVN still sucks a bit on this but it’s improving.

    I will try Git when it has a super-duper IDE plugin that totally hides it, with gorgeous visual merge stuff etc. Version control is not programming, I don’t buy “teh”‘s argument. I should not become a VCS expert for the same reasons that I should not become a filesystem and volume management expert just because my source files are stored and backed up somewhere.

  7. “If I had asked people what they wanted, they would have said faster horses.”
    –Henry Ford

    Often I find that when someone decides that a better solution to a certain problem is to scrap everything and start over from a *completely* different perspective, people don’t even recognize the problem that the solution addresses. How can a solution that’s so different be addressing the same problem that I thought was solved in 1990?

    Git is opinionated software. If you don’t agree that the premises it tries to address are the premises you should approach software from, then it is probably not for you.

    As for me, I can tell you that when I went to uni a couple of years ago, my friends and I were forced to learn cvs and subversion. For us, git/mercurial/bazaar were a revelation. Being able to branch and merge trivially freed us to “grow” software organically, to play with features, throw them away, and intelligently select code. The idea that we could manage our code, and not have to think in versions and prescribed design patterns was completely freeing in a way I can’t express.

    Maybe it’s not for everyone. Do what you want. But I love it. And I do think it is telling that few youth pick svn over “modern” systems. And I do think it is telling that Google code switched to mercurial.

  8. If you want to refer to your commits by more descriptive names than their hash number, you can do “git tag 1.8”. Henceforth you’ll be free to do “git checkout 1.8” or “git show 1.8”, etc.

    Also, if you want the version of foobar.doc from the previous commit, the easiest thing to do is probably “git checkout HEAD^ foobar.doc” (or “git checkout 1.5 foobar.doc” or such, for an older commit).

  9. dzhim suggested:

    Also, if you want the version of foobar.doc from the previous commit, the easiest thing to do is probably “git checkout HEAD^ foobar.doc” (or “git checkout 1.5 foobar.doc” or such, for an older commit).

    Someone said that checkout with an explicit filename is destructive. Does anyone know exactly what this alludes to? Should I fear it?

    (I do like that git show has no side-effects — as with the series on Writing Correct Code, that is a valuable property of whole programs as well as functions!)

  10. And another thing…

    “You’re correct in that git is not as easy to make tiny commits,”
    @david Arguably this is the point of git. No one’s saying it’s perfect or it doesn’t have quirks, but the whole idea is to commit lots of small commits so that you can bisect later if you introduce a bug, and you don’t have to wait to checkin.

    And for the record, after the initial (steep) learning curve, I have never had a problem with managing small commits, although the mistakes detailed in the OP do sound familiar.

    “Version control is not programming,”
    @Osvaldo Philosophical arguments aside, version control is indistinguishable from engineering now. Version control is what you use when you want to submit a patch to an OSS project. Version control is what you use when you’ve introduced a bug and you want to find out where it happened. Version control is what you use to develop new features by proxy. Version control is how you (easily) experiment with an idea that may or may not work. Version control is how you track who has changed what, and therefore don’t break the build every time you alter something.

    Jobs where you don’t use VCS are rarer and rarer. If you walk into an interview and have no experience with any of it, you will not get hired. Universities teach you to use it, or expect you already know how. You don’t have to know its implementation details, but just like a filesystem, yes, you DO have to know how to use it.

  11. maybe you failing because you are trying to use git as if it is the same as SVN or CVS. Here is the explanation about the creator of the thing about why it is the way it is:
    I think it makes sense.

  12. I’m glad I’m not the only one! I’m also not necessarily drinking the “easy merge” kool-aid. Although GIT may be better than SVN at masochistic mega-merges of highly divergent branches, its been my experience that SVN is actually better than GIT at figuring out how to automatically merge my revision of a file with my co-workers revision of that file. It actually figures out that if I add one line of code on line 52, and my co-worker didn’t have any changes on that line or even anywhere close to it, perhaps the merge result should include my added line. Call me crazy. SVN figures that out – GIT doesn’t, and that’s the real world merging that I have to do every day, and I suspect that a lot of other people are in the same position. I’m sure GIT is fantastic for merging a bazillion private branches of the Linux core, but doesn’t seem so great for developing LOB apps in a small team.

    flamebait! ;-)

  13. First of all, I’m a git n00b too, so I could be completely wrong about this. But it looks like you have a fundamental misunderstanding of how git works. With git, you are the admin of your own source repository. There is no “master” repository unless the users want there to be one.

    When you pull-ed from the online repository, you were pulling those changes into your own repository. Once all conflicts have been resolved, you can commit all the changes into your repository, and then you can push the sum total result, including your changes, up to the online repository.

    Whether rebase can do that I don’t know – and couldn’t figure out from the docs! I get the feeling Linus doesn’t know how to write clear English prose, and that’s a major problem with git.

  14. Ken_g6 says:

    But it looks like you have a fundamental misunderstanding of how git works. With git, you are the admin of your own source repository. There is no “master” repository unless the users want there to be one.

    You are of course right. But here we have a fine example of git’s failure to degrade gracefully — git’s much more general model of who pushes to and pulls from whom should of course have a CVS-like one-central-repository model as a trivial degenerate instance of the more general model (and indeed it looks to me like this is how most real git projects work, at least from looking at github). But it doesn’t work. The model doesn’t degenerate gracefully (as this very example of multiply committing the same changes shows). That does suggest a fundamental misdesign to me: the generalisation of the centralised model doesn’t encompass the model that it’s meant to be a generalisation of.

    When you pull-ed from the online repository, you were pulling those changes into your own repository. Once all conflicts have been resolved, you can commit all the changes into your repository, and then you can push the sum total result, including your changes, up to the online repository.

    Then why don’t I have to commit my colleagues changes when there isn’t a conflict? They’re still being merged into my local repo, no?

    Whether rebase can do that I don’t know – and couldn’t figure out from the docs!

    I have never, ever understood all the love that git rebase gets. It’s basically a tool for lying about history. It should be called git revisionism or maybe even just git lie.

    I get the feeling Linus doesn’t know how to write clear English prose, and that’s a major problem with git.

    I’d like to think it’s that simple; but plenty of other people have tried, too, and either they’re all bad writers or the model is just too complex and/or inconsistent. On the other hand, maybe the Pro Git book will be the one that does it for me.

  15. The example part (“Explain yourself, Taylor!”) is SOOOOO fscking familiar it’s not funny. I loved the file-by-file aspects of git, but now I dread these obscure corners that git puts me into all the time.

  16. @Pat, I use git every day for both job and school, and I assure you that git DOES do that. If you can’t get git to merge a project whose differences consist of one line, you are using it wrong.

    If you’d actually bothered to read about it or use it, you’d know that git has a number of merge strategies that svn doesn’t, and in general is not just faster, but also more reliable. I can tell you this first hand. When I merge a project with svn, I spend a week planning it and a week doing it. When I merge a git project it takes me …. a day? Tops?

  17. Alex said:

    When I merge a git project it takes me …. a day? Tops?

    Why would anyone consider it acceptable to spend a day merging a project?

    Maybe git is most impressive when you have very low expectations?

    (For anyone who’s wondering, that comment was 40% humorous, 45% serious as 15% Just Plain Snide.)

  18. I’m a huge fan of git (having suffered through both CVS and SourceSafe at one point or another – the pain) but regardless, this post is fantastic, and entertaining, writing.

    And at the risk of sounding absolutely trite, at the end of the day isn’t the important thing that we actually use some form of version/change/source control at all, implementation be damned? After all, isn’t that what separates us from the monkeys?

  19. Git’s poor usability has a lot to answer for, and I’m frankly surprised how quickly git power users explain it away. In my experience, Mercurial is much more usable, just as powerful, and can certainly be used as a drop-in replacement for centralized version control. The model really isn’t so different. The only real gotcha is the bloat caused by adding large binaries, which are really better stored in centralized systems which only checkout a snapshot.

    Although it will give better feedback, Mercurial will also require you to commit your teammate’s change during a merge, though for clean merges you can mostly ignore this fact.

    In the old centralized model, you try to commit but can’t because the repo has new changes. You update, merge painfully, then commit back to the repo. Note that you *never store* a copy of your change as you intended it, only the merged change.

    In the new DCVS model, you commit your change locally, storing the change as you intended it. You try to push, but it fails because the repo has new changes. You pull the changes and merge them in. If the merge happens cleanly, you can just commit it (hg commit). If not, you have to decide what you want before committing it, and this means reading your teammate’s change. Either way, the merge (which might have introduced a bug) is its own change which can be examined separately, which is far better.

  20. Didn’t you just forget to “add” the file in question after you resolved the conflict?

  21. i highly recommend trying mercurial.

    as the technical lead in my design group writing and android app with a bunch of non-cs majors, after making the switch from git to hg, the improvements were phenomenal.

    i didn’t really realize it until reading your post, but one of the biggest differences between git and hg is that hg actually gives you very helpful error messages, telling you what command you should probably try next.

    sure it may not be quite as powerful or light branching as git, but it works, and it lets me check in and merge and do all the basic things i need to do without cryptic error messages that confuse the hell out of me.

    and as you said, it may lead to me learning more about git in the future when i need those cool features, but as far as intro to dvs’s goes, hg is where it’s at.

  22. Mike, the fact that you can’t envision a project complex enough, with enough overlapping changes, that it would take a day of emailing your colleagues to figure out what needs to stay and what needs to go speaks volumes to your understanding of the subject.

    What I’m saying is, go be “snide” somewhere else. The rest of us have intelligent discussion to be had.

  23. Alex wrote:

    What I’m saying is, go be “snide” somewhere else. The rest of us have intelligent discussion to be had.

    Just to be clear: you’re banning me from my own blog, right?

    Just so long as I know.

  24. Alex wrote:

    Mike, the fact that you can’t envision a project complex enough, with enough overlapping changes, that it would take a day of emailing your colleagues to figure out what needs to stay and what needs to go speaks volumes to your understanding of the subject.

    Actually, it’s more that I can’t imagine a project that badly managed. Not where I work, anyway.

  25. when I was a SCM total noob few years ago
    (eg. never used a SCM before)

    it took me 2h to understand CVS (and nothing else existed)
    and I spend the rest of the time writing code

    then a bit later I learned SVN in 2h too
    and again I spend the rest of the time writing code

    then for the fun of it I tried Hg,
    ok distributed SCM, a bit different, it took me about 2h to know the basis and get things going
    and again I spend the rest of the time writing code

    Not with Git.

    I tried it, like the others, I tried with GitHub, and I purely wasted 4h of my time, and I did not write any code.

    So sure it may be my fault, but if I can learn all the other in 2h or less, I expect the same with Git, I don’t expect to be brainfucked by a new philosophy blah blah blah it’s “change revision” not “source revision”.

    A tool is something that is supposed to help you, not something that get in the way.

    My advice, as much as I can give one:
    – go directly with SVN, forget the rest
    – apply a basic rule: when you write/edit code always be connected to the Internet (hence no need for Git local stuff)

    unless you’re working on huge projects like the Linux kernel or the Mozilla code base which need Distributed SCM

    see here for an interesting story with nice pix

  26. Ur doing wrong. In the first few paragraphs you describe a horrible svn-like work flow combined with making changes to the same place of the same file as your peer. To that I would say get some new workflow, manage your own remote & communicate.

  27. Fundamentally, git is a platform, not a fully-tailored, off-the-shelf solution. Judged from that point of view, which is where I’m standing, I think the natural reaction to most of these arguments is a kind of “yeah, so what” shrug.

    If you don’t get it or it isn’t working for you, that’s fine, it almost certainly means that you don’t need git to solve the problems that you are currently facing. Cool, go you. But there are plenty of people and projects that do need exactly what git provides.

    Different strokes, different folks.

  28. >>Just to be clear: you’re banning me from my own
    >>blog, right?
    I’m not banning anyone, but I don’t think you should get immunity from rebuke just because you run the site. I come here because I like a lot of what you post, not because I worship you.

  29. So, basically you believed someone when they said “its just the same as CVS”.
    Then you found out it is not, and you are hating git because of it.

    Get over it. This is not a problem with git, it is a problem with your perception.

  30. You’re still an idiot.
    All you need to do is “git add ” before commiting the merge.
    No need for stupid commit -a (which imho should be removed entirely)

  31. >> Actually, it’s more that I can’t imagine a project
    >> that badly managed. Not where I work, anyway.
    The funny thing is, it’s even harder to imagine if you use git, because branching and efficient merging is designed to expedite this process.

  32. Pingback: Still hatin’ on git: now with added Actual Reasons

  33. The time you spent researching and writing on this issue could have been used to learn Git fairly well. Good luck using CVS for the rest of your life.

  34. By what metric are you claiming git is
    that much more popular than mercurial?

    When I stopped using darcs because of
    popularity (and speed) issues, I considered
    the alternatives and git and mercurial both
    seemed popular and stable enough (with
    bzr a distant third). I ended up choosing
    mercurial because it was a lot simpler,
    and also because google code’s project
    hosting supports it (and not git).

  35. @Alex: I do know how to use a VCS; in fact I’m the local VCS expert at my company – I get to execute tasks from integration to Apache HTTPD and Windows AD for auth, or some svnadmin when it’s needed. I’m also the project lead of most projects I’m involved, so I usually manage branches etc. Did the same previously for ENVY and CVS. But 90% of the time (the good part of my day) I’m just banging code, and I want a VCS that doesn’t require any effort, any thought, or any typing – just some point-and-clicks to commit, update, merge, check history, etc. SVN + Subclipse gives me that. Any VCS that’s not trivial to use for the simple tasks that are normally 95% of your workflow (at least in small-to-medium projects, not Linux Kernel size projects) is a big fail, at least for all those non-huge projects.

  36. For the love of god don’t go back to SVN. Instead try Mercurial or DARCS.

    You definitely have a point that the git command line is horrendous. It doesn’t make the simple things simple at all. It also exposes a whole class of functionality (mailed patches / rebasing) that is tremendously useful, but which you can live a healthy source control life without.

    However, the internals of git are elegant and provide a sensible set of primitives that are actually much easier to fully grok then the subversion internals, which are a dead-end and result of muddled thinking.

    Some of the things you think you don’t need from git are issues that will cost you thousands of hours over the course of your career due to the fundamental brokenness of svn. If you are a designer or work primarily with binary files then I can understand the argument that svn is good enough.

    However if you are a professional developer you owe it to yourself to learn a decent VCS. Convincing yourself that svn or cvs is not a drain on your productivity because you only have a very simple workflow is a lot like the Java developers of 10 years ago arguing til they were blue in the face about how unnecessary closures were. It may drive traffic to your blog, but man it makes you look ignorant.

  37. I made it all the way down to here in the comments, so I might as well repeat what others have said.

    git add

    would solve your original problem. Not to be another smug git weenie, but I think what you’re missing is that git allows for _crazy_ granularity when building up a commit. git add -i (for example) will let you add individual changes from a file to the index, so when you are in the middle of refactoring some 10,000 line turd that the guy-who-no-longer-works-here-but-wrote-half-the-backend left you, you can do it incrementally, and have those changes tracked.

    It’s def. more work than just doing the rewrite and committing it, but (sometimes) it can really be worth.

    YMMV of course.

    Small p.s. – 100% agree with whoever said that git commit -a should be removed. It’s often recommended as a sort of crutch for those coming from SVN, and ends up causing more confusion than anything.

  38. You can solve your first problem by doing git pull –rebase instead of git pull.

    Also, your refusal to branch is what’s hurting you. It’s really simple. Every different task you do, a bugfix, a feature, whatever, put in a separate local branch. Just do it. When you do it, git actually works. You might not think you want to branch, but you do. Not only will Git actually work, but you get all these other benefits. For example, you’re working on a feature, but you have to push this bug fix out. With a few commands you can sweep your unfinished feature aside, fix the bug, and rebase your feature on top of the bugfix. Awesome.

    What it really comes down do is that Git is a dangerous UNIXy weapon. It’s the Hole Hawg.

    If you don’t do it right, it will kick your ass. It is incredibly powerful and capable of anything. That means it is also capable of doing all the things you don’t actually want to do. If you don’t understand it, and aren’t willing to learn it and learn to wield it’s mighty power, don’t use it. If you want to wield all those incredible powers, you must train hard. They don’t come easy.

  39. I feel your pain, but it really doesn’t matter which VCS you choose. The fact that you chose git and it didn’t/hasn’t worked out for you — thats cool, but it doesn’t mean git is broken. It doesn’t mean your brain is broken either. It just means you don’t get along.

    The only thing I take exception are the following assumptions :
    a) Trying out a different VCS is risky
    b) DVCS is unnecessary except for those coding the next version of Linux.
    c) Git pushes you around

    First what is risky about spending a weekend with a new source control system? Copy your source to a different location and have a go. Don’t then just add, commit, push, pull or whatever — try out a branch, a merge, rolling back to a previous version etc. Evaluate the damn thing! The fact that you bumped into these things late in the game is your own damn fault. You don’t buy a car without checking it has a spare tyre, why use a source control system that you have no idea how merging works?

    DVCS (when it suits the developer) is a wonderful thing. Using a computer game analogy, it it the difference between being able to save whenever you like, versus being able to save only at the beginning of a new level. It just gives you a few extra layers of control over the checkpoints in your source code. With extra control comes extra cognitive load, and you have to be prepared for that. However, I would humbly suggest that if doing things at the command line gets your goat, hop onto Mercurial and use TortoiseHG or similar. The ability to keep a local repository of source and history (even bugs with fossil) seperate from your colleagues has real and tangible benefits. I won’t go into those here, they exist on the front page of almost every DVCS website out there.

    Finally, no tool pushes you around, you choose how to handle it, if at all. You are wrong when you say a good tradesmen blames bad tools. The reality is that there are only right and wrong tools.

    If you actually used the wrong tool on a production job, then you were an idiot for not testing it out to make sure it worked the way you expected in the first place. If you didn’t have the time to properly test it, should you have moved away from your previous tool at all?

  40. As a complete DVCS noob, I couldn’t agree with your post more.

    I tried an experiment a while back with Hg – I cloned two repos, made conflicting changes, and tried to push them upstream. It complained, told me to merge, and everything just worked.

    Recently, I tried the same experiment with (Tortoise)Git – it was a nightmare.

    If you’re interested, read about it at

  41. > nine tenths of the point of version control is so that my colleagues and I can hack on the same code-base together. {snip} If I decide that Darcs is the answer for me, then I have to persuade all my friends to try the same experiment at the same time. Not gonna happen.

    I’m not sure that’s completely correct. You don’t need to persuade them to try the same experiment *if* the version control you’re using is easy enough that you can just teach them the handful of necessary commands they’ll need to work with you.

    If the lesser-used tool you choose is actually substantially easier than the competition, I think you may be able to get away with it.

    Bzr has a reputation of being easy. It might pay to just put in a night or two with it before diving headlong into Git wizardry school.

  42. John said:

    You don’t need to persuade them to try the same experiment [i.e. moving to Darcs or some other minority DVCS] *if* the version control you’re using is easy enough that you can just teach them the handful of necessary commands they’ll need to work with you.

    Sorry, but I think that’s a recipe for disaster. Trying to get by with “only the handful of necessary commands” in git is what got me into this fury in the first place, and I can’t imagine that the same kind of thing wouldn’t happen to any colleagues who I persuaded to join me on this quest. Only this time it would be even worse, because I would be the closest thing we have to a Darcs wizard, so it would fall to me help them with their complicated problems as well as my own.

    Come to think of it, this is probably pretty much what did happen when my colleagues and I moved from CVS to git: one or two of them learned it deeply (although to be fair they are often pretty angry with it, too), and I am one of those who was told that I could use “the handful of necessary commands”.

  43. You’re basically talking about a usability problem. The way recovering from a conflicted merge works in git is that when you’re done resolving a conflict, you “git add” the previously conflicted file to tell git that the conflict is resolved. “git status” actually tells you this, but I don’t blame you for not noticing this, because it took me forever to figure it out too.

    So the problem is that the user interface has a usability problem, and as usability problems often do, it led to the user making errors and not being able to solve their problems for a long time. Some of the comments even have the usual “it’s that user’s fault for not understanding” nonsense.

    “git commit -a” is the *wrong solution* there.

    But it’s not a problem with the underlying model. You still have to do the same operation with SVN or CVS; the user interface to doing it is just a little different, and maybe more discoverable.

    I always use “git show” to display changesets; I didn’t know you could use it to look at old versions of files. The “–” *does* work, without the explicit leading directory names, when you want to display changesets (“git show HEAD^ — filename”), but what it shows you is a diff. I think “git checkout” might be the better command to use in this case: it replaces the file in your work area with a different version of itself.

    “git rebase” may not be useful to you in your work environment, but it solves a real problem. Here’s the situation where it applies. Bob and his team maintain some program and are making changes to it every day. They have a pretty clear idea of how everything works right now, but not necessarily of how everything worked a month or two ago. Alice uses their program; she has the version from a couple of months ago. Over those last couple of months, she’s added a new feature that’s important to her, in small, easily-understood changes.

    Now Alice wants to contribute her feature back to Bob and his team. But they don’t work for her, so they’re doing her a favor just to read over her patches and consider incorporating them. She wants to make this as little work for them as possible, and that means presenting them with a sequence of small, easily-understood changes, with no false steps that get undone later.

    She doesn’t work for them either, so they don’t care about whether the sequence of patches she sends them is an accurate representation of her struggle to understand their code, or when she made what change, or anything. They just want to be able to review the changes to make sure they don’t break anything.

    In this situation, “git rebase” and its little brother “git commit –amend” are extremely useful. Alice can use them to present Bob’s team with a sequence of patches against the *current* version of their code, not the version from two months ago, and to edit out all the changes that didn’t end up in her final version of the feature. Sure, it might make her look like she understood the whole system perfectly from the get-go; but the objective here is to allow them to evaluate whether Alice’s *code* makes sense, not whether Alice should get a raise.

    If that scenario doesn’t apply where you’re working, don’t use “git rebase”. But understand that it’s a very useful tool to people who do work that way.

  44. I’m sorry about the em and en dashes in my comment. Those are supposed to be minus minuses.

  45. > Someone said that checkout with an explicit filename is destructive.
    >Does anyone know exactly what this alludes to? Should I fear it?

    What this means is that the version of the file that you had in your working tree will be replaced by the version of the file that you explicitly checked out. If you had uncommitted changes to that file, they will be lost. (You could commit them first or use “git stash” if you want to save the changed file.) I should have mentioned this point above, I’m sorry.

  46. Charles Stanhope

    @Kragen Javier Sitaker – Thanks for taking the time to be helpful. If only all git advocates were like you. ;)

    Not that I’m advocating its use, but I am intrigued with fossil. I like how it incorporates the wiki for documentation along with a ticket system for tracking issues. The source code, the documentation, and the ticket system become first class objects in the system. It also appears to have a simple method to allow you to host your own repository anywhere you have access to a basic http server.

    With those combined features, you can essentially host a project without having to sign up for bitbucket, github, google code, sourceforge, etc. That’s a powerful idea.

  47. Mike,
    Please take Rob up on his offer:

    His screencasts are excellent.

    I appreciate your honesty in frustration. Let people who enjoy Git offer other perspectives so that you may also enjoy it too. It’s just another tool to help us all in our software development journey.

    Sincerely, @armmer

  48. “Fundamentally, git is a platform, not a fully-tailored, off-the-shelf solution.”

    Heh. This just reminded me of TicGit, git-wiki, and all the other terrible things people do with git.

    Yes, git’s error messages, command names, and syntax are all truly terrible. Thank God for StackOverflow (no, it’s not a good thing that I have to resort to this somewhat often!).

    Just to reinforce it even more (although I’m sure you’re sick of hearing this), I’d be interested to see how you fare with hg, particularly using Joel’s tutorial, since it seems like most of your issues are with the specifics of git. If you don’t like that, either, then ok, at least you gave it a fair chance.

    P.S.: the whole “social code” thing that GitHub pushes really works well for me (not so much for others). For instance, it’s generally accepted to create “topic branches” for things you’re working on off of someone else’s code, as that provides a really easy way for them to see what exactly you’ve changed, even if you had multiple commits.

    Don’t let the “ur doing it wrong!” naysayers get to you :).

  49. Don’t waste your time with bazaar, it has all the same issues you rant about here and previously. Plus a few more that I believe git shares, but you haven’t ranted about… like the poor way it handles diamond merges (criss cross merges it calls them). Which is all too common with all the branch on a whim and share changes around development pattern that these tools trick us into using. I find bazaar pushing me into that same maddening merge and commit pattern that you run into with the trivial conflict, even when there is no conflict at all, or the conflicts were resolved ages ago on a different branch and have long since been brought into the one I’m working on.

  50. “What it really comes down do is that Git is a dangerous UNIXy weapon.”

    Yeah, but the GIT salesmen (and women) sell it as a simple, safe, harmless drop in replacement for cvs. If you don’t use the advanced features, you don’t need anything more than these simple commands.

    That sales pitch, as Mike has learned the hardway, is total BS.

  51. Kragen Javier Sitaker wins.

    Mike, I get what you’re doing. You’re giving git lovers a dose of git’s own unreasonable medicine, acting clueless and stubborn to evoke the maximum sincere helpfulness– from detailed command syntax to horror and success stories to git paradigm lessons to philosophy about change management.

    As a result the rest of us git noobs are getting a great wide-spectrum intro to git. Keep it up!

  52. Nice article. Try hg. In the time it took to wrote this, you could be using hg almost as proficiently as you now use svn.

  53. I find this part “TRY FOSSIL/BAZAAR/DARCS/ARCH INSTEAD!” somewhat bit weird. While the whole approach is reasonable, you seem to have a huge problem with counting :)

    Nowadays, bzr is as big player as mercurial or git. Just have a look at the Launchpad to see the scale of it. And if you want to have a simple linear workflow (similar to how you normally use SVN), human-readable version numbers and all other goodies bzr will be THE choice.

    It’s bound branches are very similar in use to old good SVN checkout, just a bit better — local history, offline commits (bzr commit –local) and much better merging as you sync with repository.

  54. Alex: “Nowadays, bzr is as big player as mercurial or git”. It’s true that I was going entirely on how the world feels to me when I said that git was by some distance the front-runner. Does anyone have any actual statistics that bear on this?

  55. These articles, and the discussion, has made Git make more sense for me: Git is not a DVCS with a horrible UI — Git is a VCS which makes managing branches “easier”. This makes perfect sense; the Linux kernel *is* developed as a bunch of explicit branches; making that work is the primary goal of Git…

    Perhaps it takes a change of mentality to realise that working with branches does *not* have to be as annoying as it is with Subversion or CVS… (… and to realise that you’ve got your hands on a VCS where *not* using branches like crazy will become annoying.) Still, if that’s the primary benefit, there are other systems with better UIs; perhaps lacking some other benefits, bet being usable might just make up for it…

    Personally, I *don’t* like to (have to) manage branches explicitly — so if it wasn’t for the horrible UI, *that* would be my reason for preferring a different DVCS to Git…

  56. In his rebuttal (, Yehuda makes an important point and the reason why I switched:

    In git, if something goes wrong, you just run git reset –hard, which will bring you back to your last local commit. In subversion, it’s not always possible unless you manually stored off a tarball before you started.

  57. Alex: The version numbers in Bazaar might be problematic: If used as a “real” DVCS, and not just as a better SVN, version numbers will not be global, at which point they become a lot less useful… (It leads to some of the drawbacks of centralised version control, without the benefits…)

  58. This article made me laugh because it’s so familiar. When I first started using git, it completely munged my local copy many times, sometimes to the point of unrecoverability. I yelled and cried and swore to all my co-workers that there was no way I was going to keep using git.

    Now I use it on every project, and I often wonder what happened to that crap tool I was using. Did git just get better?

    Git has a completely different idea about how to manage changes than Subversion or CVS, and without understanding that idea, it makes no sense at all. Once you get it, though, git becomes this magical tool that has a solution for any situation. I don’t think that’s great for usability, but I’m pretty certain Linus doesn’t care.

    Don’t listen to the haters, as they will turn you off from git. Keep using what works for you, but experiment with git. Using git-svn on an SVN repo is a good way to try git but have a safety net.

    I hate to say “read this 31-page PDF”, but seriously, read this 31-page PDF: It changed me from hating git to understanding and still hating git. I didn’t start loving it until using it for another few weeks.

  59. Clinton R. Nixon wrote:

    I hate to say “read this 31-page PDF”, but seriously, read this 31-page PDF: It changed me from hating git to understanding and still hating git.


  60. Short version numbers in bzr are meaningful in the given branch. Across different branches you can use revision-id’s, which are way more sensible that those of git or hg. For example following revision-id: explicitly tells that commit was done by “”, commit time is 2010/05/06 10:37:40 UTC. Quite plenty of information.

  61. Pingback: My Common Git Workflow « Katz Got Your Tongue?

  62. Your name has been noted just in case I’m ever in a position to veto a hiring decision and you’re the candidate.

    Carry on.

  63. i’m a fan of git–migrated to it from svn last year, and prefer it for most of my code management–but understand where you’re coming from about its inscrutable error messages. i don’t mind being pushed around by a tool, but i prefer being pushed toward a solution (“here’s what you should be doing…”) rather than merely being pushed away (“no! you can’t do that!”)

    that said, i honestly didn’t expect such hand-holding from git’s command-line client, and scott chacon’s and others’ tutorials brought me up to speed pretty promptly. you’re right that i wouldn’t expect vi to demand a specific indentation style, but nor would i expect it to explain that i need to be in insert mode every time i try typing in normal mode. nor, for that matter, would i expect a harrier jump jet to include a “tutorial” mode for new pilots (just pull the big red “help” lever; the one marked “eject”!) i doubt you’d hop into a harrier and expect to fly it if your only previous experience with aircraft was a biplane! :)

    nice follow-up post, though. i’d like to hear your opinion of mercurial if you do give it a serious go.

    @Darren i thought the same thing when i read that! (git wizard.)

  64. Jakub Skoczen

    Oh, I ended up reading your post since it was referred to at your favorite framework’s comitter blog

    It does not happen too often but I have to I agree with you this time ;) – Git has pretty poor abstraction of it’s internals and even though highly praised by Linus, for smaller and less dispersed projects, migration from CVS causes mostly confusion with very little gain.

    But remember that there is still a bunch of people (mostly younger devs) for whom the transition does not seem painful – they either did not use CVS at all or they did not get used to the workarounds you need to constantly apply with CVS. For me, the pure crappiness of CVS (remember all those empty dirs?) is enough to love Git.

  65. Hi Mike,

    I’m a git fan and advocate. I find it very useful, though it is very cryptic and difficult to learn. I’ve done git training classes, I talk about git on my blog, I am converting my team to git away from svn, etc.

    Now, I say that first because I want to set the stage for this:

    GOOD FOR YOU! and THANK YOU for being honest!

    Seriously… I’m tired of all the “you just don’t know how to use it” responses that everyone wants to throw around. You’ve invested some time and effort in trying to learn a tool and you find it frustrating. I don’t see anything wrong with that.

    Truth be told, it’s quite refreshing to see someone complaining about a tool that they are actually trying to use, instead of just bitching and moaning without even trying. There’s far too much of that going around these days. I think it shows a great deal of integrity on your part that you are spending the time to try and learn the tool, are blogging about your frustrations and are listening to the comments and suggestions from the responses.

    I may not agree with your frustrations or reasons for not liking git, but I have total respect for your opinion because it’s an educated opinion – or at least, is becoming an educated opinion through actual use of the tool.

  66. I’ve switched to git only for the It makes local commits, the thing that bit you worst, the best part.

    You can even split all your changes on line-by-line basis into individual commits – *easily*.

    Among those 138 commands, there’s git mergetool, which saves me from remembering half-dozen others. If there’s conflict, you run that one, resolve and you’re ready to commit (just git commit, no magic arguments).

  67. Re: your first issue with merge conflicts, that one got me too. The problem is that you’re actually asking git to do a 3-way merge between (1) remote master last time you pulled it, (2) your changes, and (3) remote master now. Of course, that’s exactly what CVS/SVN does, but unfortunately for git it’s squarely using-hammer-as-screwdriver territory.

    The fix is to split the process in two: first merge remote master now into remote master last time you pulled it and put the result in local master, and then (depending on what you want to do, and this is important) merge local master into your code (if you want to keep working) or merge your code into local master (if you want to push). This final distinction is important, it’s the biggest win that git gives you; and since adopting it I’ve never had a merge conflict I can’t easily recover from.

    Unfortunately the only way to do this is to learn how branching works, and use it. The revised list of ‘all you need’ then becomes clone, pull, branch, merge, add, commit, and push. I’d add diff and the often overlooked gitk in there.

  68. > Sorry, but I think that’s a recipe for disaster.

    Perhaps I wasn’t clear enough.

    My point was, if you are a novice-DVCS user, and if you walk into a room full of non-DVCS devs and attempt to give them a handful of commands that they can use to work with you and your projects, then you may have different outcomes depending upon whether your DVCS-of-choice is Git or something else with a presumably more sensible UI.

  69. Alex: Short version numbers are *unique* in a branch. Whether they are *meaningful* depends on how the user manages branches… Unless the user makes per-feature branches, the number doesn’t have any meaning beyond indicating some part of the “internal” state of the VCS…

    Merging changes that *don’t* have their own branch doesn’t work all that well in Bazaar. That kind of thing works better with systems that try to manage *changesets* rather than *versions*. (I have a hard time considering Bazaar a serious DVCS; the “distributed” part *can’t* be made to work right with a numbered sequence of versions as the fundamental concept. Then again, it *is* distributed in the sense that branches may be maintained on different computers; I might have been spoiled by the implications of “distributed” in other systems…)

  70. Josh Jensen

    I’d like to post a few notes. Some are long, so I am dividing them into separate comments.

    First, a helpful hint: I’m a command line guy, but I find myself doing much of my work in the ugly but super functional ‘git gui’.

    The index/staging area of Git is an integral part of Git’s workflow; in fact, it is one of the primary reasons I moved to Git. Git Gui makes the staging area feel natural. In its simplest form, it shows me all of the files that have changes, files that have been deleted from the hard drive but were controlled by Git, and files that have not yet been added. From within the Git Gui, I stage the files for commit one by one so I can review diffs before commit. In fact, I can selectively commit portions of a file, say, whitespace change.

    Anyway, I have a more detailed description of the Git Gui here: and

  71. Josh Jensen

    I concur regarding certain usability issues.

    The “! [rejected] master -> master (non fast-forward)” message stinks for new users. It should be a far simpler message for the majority of users. Knowing what I know now after a little more than 2 years of using Git (on Windows, in fact), I appreciate the error message using Git terminology and tend to prefer it. That doesn’t make the obscure message right, though.

    ‘git show’ and relative paths should be supported out of box.

    And, in Subversion fashion, ‘git status’ should show from the current directory on down instead of showing everything. Regardless, as I said above, I use ‘git gui’ for all of this, so it doesn’t tend to bother me much.

  72. Josh Jensen

    I may be restating other comments above, but I want to comment on the merge conflicts you have run into.

    During a merge, all files merged successfully are staged for commit. Files with conflicts are left unstaged, and conflict markers are inserted. When the conflict is fixed, it needs to be staged with ‘git add’ or, my preferred route for staging, from within the Git Gui. The merge commit is not allowed until ALL files for the merge are staged; that includes conflicts. At that point, you can commit the merge, and all is well. I have never seen the merge errors regarding a merge in progress, because I was taught from the beginning I have to stage everything before commit. I do think the majority of Git tutorial sites out there don’t really make this clear.

    In Perforce (which I use daily at the day job and have done so for 10 years), integrations are tracked on a per file basis. This is both a blessing and a curse. It is a blessing, because I can be selective about which files I merge to another branch, and because I can often get away with performing a integration without having a latest sync of everything. It is a curse, because I am allowed to do both of those things. I have seen issue after issue with this over the years.

    Due to the tree-based DAG in Git (and other DVCSes like Mercurial and Bazaar), you can’t commit individual files during a merge. A merge has to be complete with a merge result for every file within the requested changelist. You can’t get away with Perforce single file integrates; the merge is all or nothing. This is a blessing, because I _know_ I have all of a given changelist. It is a curse for the supposed usefulness of the Perforce “blessings” listed above.

  73. Josh Jensen

    Going along with this is an interesting thread on the Bazaar mailing list: It applies to Git and Mercurial, too. DVCSes tend to require the whole tree be up to date before pushing to the remote repository. In Perforce or Subversion, I can commit any file at any time, so long as no one else as modified it. If that happens, I have to sync latest on that file first. In the DVCS world, I must have all commits local before I can push my change back.

    The key take away (for me) from that thread is that this behavior means I can reproduce on anybody else’s computer the state of my repository at the time of commit. In Perforce, for instance, I can have files synced to various different points. When I commit in Perforce, it “worked” for me in my tangled working copy. When my office mate syncs, he finds the build is broken.

    In the DVCS, I am required to push my changes on top of the absolute latest commit. That means I have to have it locally first. That means I tested my commit against a known point in the repository, and when I push it, anyone else can reproduce the exact state of the repository when I committed.

    As I have pondered this concept over the years, it really means each DVCS repository should house _one_ project. The Perforce repositories I’ve worked within have many interdependent projects within a given tree. In order to enforce this DVCS concept within Perforce (because it’s smart), I would find myself in frustrating situations. If I am working on a tool and someone else is working on a game, I have to sync down their completely unrelated commit before I push up my tool change.

    The only resolution is to split my Perforce/DVCS repository into discrete projects. So the DVCS approach forces my organization to have a better design.

    Good? Bad? That’s for you to decide.

  74. Josh Jensen

    For abandoning a merge, ‘git reset –merge’ should do what you want. It is new, sometime in the late 1.6 series or even in 1.7. I suppose that is the problem with the Internet… it would be nice to mark answers on the web as ‘old’ or even specific to a given software version.

  75. Josh Jensen

    One of the things that always bugged me about working in a branch in Perforce (or Subversion or whatever) is having the other branch’s commits shoved on top of mine when I integrate/merge. I often end up resolving conflicts nobody else has to deal with. Alex changes line 50 of file.cpp, I integrate Alex’s change, I change line 50 of file.cpp, and then Alex changes line 50 back. When I integrate Alex’s new change, it messes around with my change.

    You aren’t fond of branches, and that’s fine. I often work in the master branch, too. The example above actually applies to pushing and pulling. I discovered a better way. Git gave me the exact functionality I wanted.

    So, here I am in my repository (with only one branch, “master”), and I have the following commits in this order. Note I am not drawing fancy schmancy diagrams. A linear flow is sufficient for this conversation.

    Remote repository: Alex-A -> Bob-B -> Alex-C
    My repository (after a pull and some commits of my own): Alex-A -> Bob-B -> Alex-C -> **Josh-D** -> **Josh-E**

    Okay, now I am ready to grab the latest commits. I ‘git pull’ them in.

    Remote repository: Alex-A -> Bob-B -> Alex-C -> Bob-F -> Bob-G -> 100 more commits
    My repository (after the merge and a personal commit): Alex-A -> Bob-B -> Alex-C -> **Josh-D** -> **Josh-E** -> Bob-F -> Bob-G -> 100 more commits -> **Josh-H**

    \My changes are in the middle of other changes now. I want my changes all lumped together. I can’t even easily see my **Josh-D** and **Josh-E** changes in the log, because there are now 100+ extra commits between my changes.

    I was ecstatic when I realized what ‘git rebase’ can do. Now, instead of a straight ‘git pull’, I run ‘git pull –rebase’. The following happens:

    Remote repository: Alex-A -> Bob-B -> Alex-C -> Bob-F -> Bob-G -> 100 more commits
    My repository (after the merge and a personal commit): Alex-A -> Bob-B -> Alex-C -> Bob-F -> Bob-G -> 100 more commits -> **Josh-D** -> **Josh-E** -> **Josh-H**

    My changes are now contiguous. They even maintain their original commit date. You worry in your article about rebase modifying history. It is technically true that happened here, but I see it more as building my commits on top of everyone else’s. I haven’t published them to the world yet, so I should get to see them all together. For the example at the top of this comment, Alex’s line 50 change and then revert of line 50 will never affect me.

  76. If you finally determine that git is not for you, please don’t give up on mercurial. As others have mentioned, Joe Spolsky’s tutorial at is definately worth the read.

    I work almost entirely in a Windows environment, so git was a non-starter for me. I use mercurial at home and work. It has enabled me to have a couple of repositories for checking in changes when our CVS repository is frozen for some release-engineering process. I find it fast, convenient and has error messages that are easy to decipher as I learn how to use it. Of course, the best reason to have distributed version control is no need to be connected to a central repository to check in code.

    BTW, thanks for the pictures. I could almost feel how great your frustration must have been. I hope you’ll find a distributed version control that works for you.

  77. Even though I’m not a sushi fan, I really preferred sushi pictures to dead/rotten fish.

  78. Don’t worry, Konrad, the sushi will be back as soon as I start writing about something other than git again!

    And, Josh, thanks for your half-dozen helpful comments.

  79. Not that I expect this to change your mind, but I did find git offensive UNTIL I found someone who could teach the concepts well. Take a look at this:

  80. Josh Jensen

    Douglas: FWIW, msysGit ( works fine in a Windows environment. I use it every day. I have for a couple years now. There are certain missing features, such as ‘git daemon’, and so I’ve never used it. Perhaps it is useful, even if I had to open a port in my firewall.

  81. Hugh Sasse

    @{Kragen Javier Sitaker}: So Alice needs to use rebase and commit \-\-amend to tell Bob about her changes since the 2 month old pull.

    [I’m putting backslash chars in so that they might escape the double minus signs from becoming em-dash. This is a guess, with no preview. (Not a complaint, just explanatory.)]

    I thought \-\-amend was for correcting commits.
    It seems to mess with the history, but I suppose you
    are saying that this only happens on the one branch which Alice is going to push to Bob, and the editing allows her to spare him all the tedious detail of when the edits happened. So the fact that he gets a revisionist version of her editing history will cost him nothing, and she will still have her other branch with the truth on it, so she doesn’t lose either. Is that right?

    It might be useful to describe how she would use these commands to achieve the effects you mean.

    @Damian: Keeping a branch to reflect the unedited master is a nice idea. I can see that updating remote_master_last_time is like a patch based on what has changed between then and remote_master. You clearly want to bring it up to date, additions, and subtractions alike, giving local_master. I’m not sure how the merge with your changed code will work. How will the differences in your code due to your edits be distinguishable from those due to remote edits which have been merged? Does git make use of the common ancestor (where the branches joined)? If it effectively just makes a patch between the HEADs of both branches, then some changes could revert the update just done to local_master. But I think (hope) I am thinking incorrectly about this.

    To make that concrete and trivialized:
    remote_master_last_time was a figure of a person.
    You branch, and add shoes to it.
    You then checkout remote_master_last time,
    and pull, and find the origin has changed so it has a hat.
    If you merge in your changes, you add the shoes, but how do you not remove the hat?
    Or the other way, add the hat to your branch and not remove the shoes. This is assuming that the top of the person doesn’t conflict with their toes.

    I’d imagine the philosophy could be “prefer additions” over deletions to reduce information loss, but I’m not really sure: maybe it could be “prefer changes over lack of change”, which would allow deletions to propagate properly, but if this is done by date then a rebase, even in the Alice and Bob case above, could do the wrong thing. Couldn’t it?
    Doesn’t rebase mean you can kill your grandfather, as it were?

    A long comment, sorry, but clearly I can’t frame it concisely enough to ask Google instead. I’m hoping that trying to clarify this will help someone else as well.

  82. The step you are missing is:

    git add file-you-just-resolved-conflicts-in

    After that, git commit will work.

  83. Paul Winkler

    Mike, one more thing about mercurial that might be relevant, since your coworkers use git:

    It’s a mercurial plugin that allows you to push to / pull from a Git repository. So you can use hg locally and your coworkers can use git and everybody’s (presumably) happy.

    It’s beta, so YMMV. I tried it for one project (the project that forced me to start using git) and hit this bug:
    … apparently fixed now but I haven’t yet tried it again.

    Like you, I don’t want to invest a lot of *up front* time in learning a DVCS. I want a bicycle. I want to get on with my work and learn useful techniques as I go. I feel like with git I’m frequently stumbling because I don’t understand enough of how to use it properly, so I have to stop what I’m doing and go read git documentation for a couple hours before I can get back to work. Admittedly, hg shares a lot of commands with SVN, which I already knew, and they mostly work in similar ways, so the learning curve is a lot less steep for SVN users: you really only need to learn push and pull and you can start doing useful work. With hg, in my limited experience so far, that’s actually true :-)

    It’s been so long since I’ve used CVS that I don’t know what the transition from CVS directly to Hg would be like.

    It also has shorthand revision numbers, like 1, 2, 3… which aren’t meaningful outside your local repository, but are still quite handy.

    Oh, and – joy! – like git, hg has a bisect command.

    I haven’t used it in anger on a large active project yet, but so far, hg feels a lot more comfortable to me.

  84. I recommend using git pull –rebase instead of git pull. This will more closely mirror what you would get with subversion, where all commits to a branch are linear and you don’t have to perform a merge just to be able to push.

  85. Can I please recommend that you give darcs 2.4.3 a shot? I think you’ll find that it fits your mental model of how version control should work while offering you all of the power of git. There’s a nice description of migrating from cvs to (a VERY OLD VERSION OF) darcs at .

  86. Wow… I mean I do recognize the tongue-in-cheek style and that you are venting, but the whole post is so terribly off the mark it’s hard to find it funny rather than sad. I really hope new software devs are not going to take this rant as advice on how to choose an SCM system.

    Comparing branching to influenza… I can only assume, from this post you just work alone a lot. I mean I kind of get it, I hated and avoided branching with SVN too, and I know git has a bit of a learning curve (I had easy access to someone with more experience to help with my transition).

    However, I realize this is just a needed vent in the fustration of the learning process. Trust me, stick with it, you will hit the end of the curve and the frustration will be worth it (or feel free to give Hg a try, people tell me it’s easier *shrug*)

    I can say from my own personal experience the productivity I’ve gained moving from SVN to git has been huge. Learning how and why to branch has also been a god send. Keep on going, nothing worth learning is ever easy.

  87. Pingback: You could have invented git (and maybe you already have!) « The Reinvigorated Programmer

  88. I think I’m getting resolved to git and resolved to Mike.

    Clearly “add” was the thing. “Add” has to do with “stage,” they both mean, “Okay, this is one of the things my next committed change is going to be about.” “Commit” means, “Now I’m sure that’s the complete set.” I don’t understand why commit -a isn’t a good idea when you think all the changes you made are good.

    Why all the merged files but the one you needed to merge are automatically added puzzles me. Maybe because they had no conflicts so it’s less of an issue whether to add them. Or, you never changed them so you shouldn’t have to add them.

    Mike, I resisted, but your wtf rants and starting a brawl are cool. Everyone should have a WTF bottle, or at least a tiny wtf bottle pendant.

    There definitely is such a thing as a bad tool. And everybody is right quoting, “Simple things should be simple, complicated things should be possible.” git is a workflow tool that seems to have no concept of flow, just puzzle pieces of a picture of a garden path.

  89. Forgot to say I loved the alternative git sushi in their alternative serving suggestion setting.

  90. Judson Lester

    I continue to feel that what’s loved about git are the DVCS features of it – most importantly that you don’t have to merge before you commit, like you have to do with CVS or svn – you just have to merge before you can push. Whereas I don’t think that anyone claims to love the UI.

    Frankly though, I’ve always had great affection for monotone ( – it’s theory of operation is much more intelligible, I find, and it goes as far as saying that you needn’t ever merge. Likewise, it works better with merge tools, in my experience when you do merge. Largely, the niceness of Monotone seems to come from the approach of the VCS as a monolithic tool, rather than a series of patches on a weekend hack project.

    That, and it leaves out (by philosophical design) the two features I dislike most about git: rebase and stash.

  91. Pingback: Top Posts —

  92. Pingback: Top Posts —

  93. > If I decide that Darcs is the answer for me, then I have to persuade all my friends to try the same experiment at the same time. Not gonna happen.

    This network effects problem is an important point for Darcs to tackle strategically in the long term.

    We think we get some things right — friendly, interactive UI; simple mental model backed by a patch algebra; easy cherry-picking on all levels. We also get some things wrong. In the short term, we’re working to fix the one thing which people seem to complain about the most (performance). In the medium term, we’ll tackle robustness and nice things like a Darcs library.

    But in the long term, we’ll need to go back to the catch 22. Even if Darcs is great, how are we going to get around nobody using it because nobody else is using it? The dream will be to make seamless git/hg/bzr interoperability work. So don’t lose hope. Perhaps over time, the entire revision control space will converge and everybody will be able to talk to everybody.

  94. Arild gets at the real issue: ‘Git is not a DVCS with a horrible UI — Git is a VCS which makes managing branches “easier”.’ You seem to have been bit by the fact that Git tries hard to plaster over the conceptual difference between a centralized VCS and a DVCS: `pull` tries to auto-merge changes from others (a bad idea!), and use of `rebase` is encouraged to maintain a linear history.

    How your case would’ve gone differently in Mercurial:

    * You make a 1-line change to a file and commit.

    * You `hg push`, which fails because it would create a new remote head. (Creating new heads on your own repo happens with no fanfare; creating new heads on someone else’s requires force.)

    * You `hg pull`, which fetches the newer changesets, but *does not try to merge them in*. You can examine the new changes, and either run `hg merge` to sync things back up, or ignore them and keep hacking on your own development line until you’re ready to merge the two lines.

    Mercurial has a cleaner presentation of and interface with the conceptual model, and it doesn’t do some of the stupid and dangerous things Git does. (It does have a rebase extension, for the times when that’s actually called for.)

  95. Jakub Narebski

    * “! [rejected] master -> master (non-fast forward)” does not necessarily mean that you need to pull first. What you need to do depends on your workflow, and how you use git.

    * ”fatal: cannot do a partial commit during a merge.” means that you cannot do “git commit file”, but must do “git commit -a” to comit merge conflict resolution. Finishing a merge is inherently whole-tree operation.

    * “If you run git tag and subsequently push your repo, the tag doesn’t get pushed.” It depends on how you configured git. You can configure it to automatically push tags. The default behavior is to require pushing tags explicitely, and it makes much sense (to avoid accidental pushes of local tags etc.)

  96. Personally, I’m glad I was lied to about being able to just use a few commands, and treat git like svn, and all the other blatant falsehoods used to sucker me into letting git into my life. Because now I’m better off for it, and I would have been completely overwhelmed if I knew I’d have to master all the crazy stuff git does just to feel mildly competent.

    Maybe not ethical, but effective!

    But yeah, I feel you. Git didn’t match my workflow, but I’m much happier now that I’m making local branches for any chunk of interesting work, making clean commits with the index, all that nonsense. I know it smacks of the authoritarian fallacy, but maybe Linus does know better than me on that particular score.

    Best of luck with whatever you end up doing!

  97. I just Love Git… and I use it for just about everything…
    There are lots of other things I just hate… and these things I don’t use for anything…

  98. Josh Jensen


    >`pull` tries to auto-merge changes from others (a bad idea!)
    > You `hg pull`, which fetches the newer changesets, but *does not try to merge them in*. You can examine the new changes, and either run `hg merge` to sync things back up, or ignore them and keep hacking on your own development line until you’re ready to merge the two lines.

    I find ‘git pull’ very useful. The Mercurial extension command ‘hg fetch’ does the same thing.

    Regardless, ‘git fetch’ fetches the newer changesets but *does not try to merge them in*. You can run ‘git merge’ when you’re ready.

    >How your case would’ve gone differently in Mercurial:

    There is no real difference between the two. Git makes both workflows available out of box, ‘git fetch’+’git merge’ or ‘git pull’.

    >Mercurial has a cleaner presentation of and interface with the conceptual model, and it doesn’t do some of the stupid and dangerous things Git does.

    This is exactly the generality (stupid and dangerous) that caused Mark to add this blog post with _actual reasons_. Post some actual reasons. You may be surprised.

  99. Josh Jensen

    Fixing the embarrassing mistake above: “This is exactly the generality (stupid and dangerous) that caused **Mike** to add this blog post with _actual reasons_. Post some actual reasons. You may be surprised.”

  100. Pingback: tekx – getting git « Internet Strategy Guide

  101. Peter Connolly

    Thanks for the cautionary tale. I have been tempted to jump on the Git bandwagon, just as you say because of the Linus Torvalds imprimatur. But after using Bazaar for the last 2 years I don’t see a good reason (i.e., becoming more productive) for switching to Git. I enjoy Bazaar because it looks and feels like Subversion yet allows me to work independently of the central repo. Oh, and it has great on-line tutorials too… ;-)

  102. Peter Connolly

    And should have mentioned in the previous post that Bazaar can use your Subversion repo as its central repo. Nice way to try it out without too much pain.

  103. Pingback: Most interesting links of May « The Holy Java

  104. Pingback: Destillat #49 – Git, Mercurial, Subversion und Co. | Open Source und Wetware

  105. if you can’t use `git help commit` and `git help merge` then you’re basically fucked. nothing can save you from this.

  106. @raggi

    Dude, if you had any brains at all you could have spent the time it took to write all these arrogant, ignorant paragraphs and post all these damn pics to actually learn the basics of git. You’d have a solid start on the most powerful, efficient, flexible version control tool available.

    I’m an experienced user of svn, hg, and git. If you are convinced that svn is good version control, you are a fool and your code is probably shit, so it doesn’t matter what VCS you use.

    As far as git and hg are concerned, what I can tell you is that while they are conceptually similar and provide many of the same constructs, the devil is in the details. There are complex situations that arise when working with large codebases and multiple lines of development, supporting multiple versions of software for clients, where nothing, not even hg, can match git.

    One important distinction is that git uses a model based on named branches whereas hg prefers clones. Clones may be easier for svn people to grasp, but you’ll figure out pretty quick that clones heavyweight style of having five different working directories adds needless tedium that can easily be avoided by using lightweight git named branches. Seriously, if you can’t figure out git, you shouldn’t be writing code.

  107. Hi Taylor,

    I have to say this is the worst git article I have seen ever and normally I would ignore it completely but that wouldn’t do git justice.

    And this merge conflict of yours. Why the hell don’t you resolve the conflict with git mergetool? That will get you out of the situation you are in. If you need to apply your changes to the existing master use rebase, cherry pick or better yet just start using topic branches and rebase from there!!!

    Your story is the story of the guy who doesn’t know what he’s talking about and is complaining about it. This is unfortunately often the case with some git newbies.

    Learn the tool and find the solutions to your problems before writing garbage.


  108. Pingback: Why we chose Mercurial and Bitbucket | CloudEngine Blog

  109. @lola

    “if you had any brains at all..”
    “you are a fool and your code is probably shit”
    “Seriously, if you can’t figure out git, you shouldn’t be writing code.”

    If you can’t be nice to people, you shouldn’t be on the Internet.

    It’s people with attitudes like yours that gives Git (and other things like Ruby, Rails etc) a very bad name, and turns other people off (like me) from even going anywhere near them.

  110. Having used (in no particular order), rcs, cvs, svn, designsync, bitkeeper, monotone (extensively), git (struggling to get productive) and fossil I would say that based on some of the comments above there is a huge ROI to git if you are a highly distributed team and need to do a lot of complex branching and merging. However, if you are a smallish team with decent communication and plan only on a handful of formal branches and the occasional local branch then you are way better off with one of the simpler tools. My favorite by a huge margin is fossil (although monotone was amazingly rock solid for the years I used it). Super easy install of single executable on windows, linux etc. Wiki documentation and tickets come for free and a useage model that is a relatively easy transition from something like cvs or svn. I love the autosync. Pretty much the only rule you have to learn is to do “fossil update” and “fossil ci” regularly. With reasonably savy users you don’t have to do formal training. Not so with git IMHO. I’m learning git because our team has settled on using it but the training effort is much higher than fossil and I don’t think it will be pretty when the naive users come on board.

  111. most of people use git not because it’s better (it isn’t), but just because they hear that if you use git you are smart and if you don’t you are stupid. And they looks like have some problem with that..

  112. Gregg Lebovitz

    A colleague pointed me here. I admire your tenaciousness with git and willingness to actually raise questions about the appropriateness of git. I for one am too stupid to figure it out and rely heavily on another tool called SKYPE to get me through most my git tantrums. Particularly useful are eastern European programmers with several advance degrees, who are able to quickly grasp the concepts of git and distill them down to level even a monkey could understand.

    This is important because everyone keeps telling me that the familiar tools such as Qt, GTK+, .NET, and even Silverlight are all going the way of the model T and will be replaced by HTML5. They also tell me that my years of experience in algorithms, models, abstractions, C++, C#, and C are about to be obsoleted by teams of young hip design school graduates toting kitsch leather shoulder bags filled with HTML5, CSS, and Javascript neatly laid out with graphics design tools far beyond my comprehension. I am led to believe that the tsunami is coming and I should somehow get out of the way.

    I only point this out because, I don’t think these new breed of developers are going to give a flying bubbletruck about git. But I digress.

  113. Pingback: Why you should never employ a techie to solve your problems!!! | The Agile Radar

  114. I think git has much to teach us, but it’s just one more step in the evolution of revision control.

    There has GOT to be a better way.

    Heck, even if the names of commands were chosen more carefully, it would be far more usable (and therefore palatable). But, alas, I think that the massive proliferation of commands is a bad sign that something is fundamentally broken with git.

  115. TL;DR: OP tried Git for a couple of days, and instead of using the time to RTFM, wrote this rant instead.

  116. Steven Pennebaker

    you might look at some of the pretty clients (GitX, SourceTree), they make the experience slightly less annoying. same mess, but with a paint job.

    in discussing git w/ colleagues, being terse, i tend to skip directly to “I. Do. Not. Care.” because, to me, source control is an absolutely necessary safety net which i do not want to think about at all except when a jump gets missed. git, on the other hand, believes that the most interesting part of the circus is the safety net, not the high wire act. BOTH components are required. my colleagues, were they terse rather than polite, would skip to “You. Ignorant. Old. Fart.” and would have a point, because there’s a different work style implied and if they can keep track of what’s going on in 50 different experimental branches and how all those branches interrelate (they can’t), more power to them. i’m more of a solve-and-move-on kind of guy; very unfashionable.

    great, even-handed post, thank you.

  117. Real World Coder

    @David Turnbull
    Dude? Is that a joke? GIT is the absolute worst tool for complex code. Sure, if you break your project into many feifdoms and put a MAINTAINER on each; but, that’s simply a rare and unique situation. Most projects are balls to the wall get something done, delivered, and working by a certain date. Throw GIT into the mix and the project cost balloons 10%-40%. Just my experience in two medium-sized projects (one for Viacom and one for a large FI) and many, many projects with a whole range of other SCS’s. I haven’t used TFS; but have used most of the others. If you want a sane and progressing project you can use SVN. If you want the same but bad merge support then use Perforce. If you want bad merge support, lots of strife, use GIT.

  118. Used CVS then SVN for years. Then company I work changed from SVN to git. The project is huge, with more than 200 people on it. Since I work intercepting emergencies I have to do several fast changes in several dozens branches, usually acessing at least 20-30 different versions per day, pushing single small changes on precise places. That was so easy with SVN, so easy to know what revision was ahead of the other among other things

    I never ever before faced anything in my whole life that made my life harder than git did. In a single year, my detailed accounting of time spend gave me the following numbers. 117 hours FIGHTING with git and another 734 hours lost of work merged wrong by git.

    In 15 years before I had never ever lost more than a grand total of about 2 hours dealing with version control. I need something simple because my mind is far more capable of decision than any automatic system git can provide and I want a tool that do what I want.

    How I improved my productivity back? I code, do a clean CLONE of the repository, re apply each thing I want to the code, commit, push and delete the clone. That was the only way I could prevent mistakes keep getting to clients. Because I trust git less than I trust an alcoholic in a wine storage room.

  119. Wow — some very harsh words for git there. I suppose I am sort of reassured that it’s not just me — that even people who do version control more or less as their jobs are running into similar problems.

  120. Pingback: Dear git: STOP CHANGING DEFAULT BEHAVIOUR! | The Reinvigorated Programmer

  121. Sir…. Y.A.N.A. !!!
    The horror! Just wait until you look at replacing remote branches or reusing external projects in any other scenario than whole-repo-under-my-repo (as in svn:externals). Sooo straight forward… after a day of reading or more. No… I take it back.. Just don’t do it. Just don’t… Make it a build step. Hmm. Source part-control we’ll call git.

    AH! I absolutely love that arguments like ‘but it’s what the kids are doing’ and ‘what google did’ are actually treated as… well… arguments. Hilarious. I know I base all my architectural decisions of what’s cool and hip with the kids! Don’t you? After all, they have all the intellect, the insight, the hard-nosed, hard-won experience and… hang on… Hmmm… Could it be they didn’t know how to use SVN (set up a local server if they were that keen). And of course – let’s not forget that it’s soooo much faster to check out to your own machine and… :$ Seriously? In some scenarios (it’s called corporate programming) having a simple, centralised repo system is a good thing! Ah! But… but can SVN force every checkin to be a merge (the nutshell of your post problem), then say it does so ‘better’ because you have to to make any meaningful change upstream? Check-mate, svn! (WTF!?)

    Oh yes, while we’re talking about mindless pro-gitters who don’t seem to understand that the application of the tool is what makes the tool (period!), and… while the sarcasm is thick: google code’s gone to mercurial… *Damn* that’s a powerful argument for git… (WTF again?) And hmm. Let’s see. Mercurial is closer in impl and usage to svn, but is a DVCS. Yeap. Looks like google were *really* impressed by Git.

    Ah, I could go on forever… but unlike the git manual, I’d rather say what I meant briefly without being overly terse where it actually mattered, then shut up. Linus should have stopped at his revamped kernel. that way people who know more than how to use github wouldn’t think he’s quite such a twit.

    And one final blast. Wherever I find git in a corporate environment (precious few!) I ask what they assessed to come up with it. “We just used github” is the invariable answer – nothing else was trialed, tested or even studied! I call this phenomenon “git from github”. It’s not a compliment.

    Ah! And as for the green little darlings who pour on abuse for your not using the magic tool or command, I say: reread. The point is that the technology is overly complex and poorly documented; that it forces a certain workflow which involves (seemingly) massive re-education. If you never thoroughly learned the previous VCS out there – or alternative DVCS – of course you’ll have all your time to devote to reading (terrible) git documentation. (But who knows? Perhaps they can’t read sarcasm when you pointed out the appallingly esoteric error messages – guru message anyone? Hmmm. But who of the nappy-wearing meat-head developers who can’t work out how to merge in svn are going to get that reference?)

    *Waits for the next fad and the fanboys who attack anyone not mindlessly jumping on board* If we bothered to learn more about our history the future wouldn’t be in jeopardy.

  122. Chris Gomez

    I am going to say as someone who has transitioned fully to git and is never looking back (from DVCS at least with the GitHub style workflow), git is hideous to use.

    The command line jockeys (might) feel superior and smug, claiming that it’s your laziness and living in a gui (perhaps) that makes it so hard for you.

    But that would be complete folly. The reality is the commands are obtuse and you do have to learn specific incantations to do what you want.

    I’ve used a variety of GUIs to help with the experience. Github for Windows makes a lot of the git commit -a pain go away. The built in VS 2013 tools are great at picking and excluding what you are and aren’t ready to commit, and you can switch branches with ease, but that’s about it. SmartGIT seems to be the most fully featured tool I’ve come across so far, but it speaks in terms of the git lingo, so you have to know it.

    For example, I love the concept of fast forward merges. I can work in a branch and not affect anyone else on my team, committing without breaking anyone else but preserving my work for another day (either to rollback because I decided to do something else or the dreaded hard drive crash). However, DOING a fast forward merge was an exercise in learning the incantation and how to proceed along the way in resolving conflicts. NOW I am proficient at it, but let’s be honest, that is terrible UX. It does exactly what I want to do much of the time… which is to say… “put my work on top of the commits other people have merged and reviewed, as if I didn’t start my work until just now.” I find it a time saver and work saver over, for example, “SVN merge mania at the end of a feature”

    That’s just one example, but the command is git rebase master (or similar) and you have to figure out or read that you need to resolve the conflicts along the way and re-commit them. It’s all very strange. And if you get lost, then little it there to tell you to reset hard to put it all back. New users resort to just throwing the repo away.

    So, while I love the git concepts, and the tools I can use to be very productive, the UX is just awful, and THAT’S what the Git community should embrace… solid cross platform tools built on top of it. Sneering at not wanting to use the command line is honestly just pretentiousness. Normal people want to get work done and provide business value.

  123. My two cents on this mirror what I believe the writer is getting at. Version control is not programming, or shoudln’t have to be programming. I am not averse to the idea that I should learn it better and things would be easier.

    But my question is this, how many hours should your average user need to spend to learn to use a VCS? In my opinion very few. Most large organizations have SCM managers who delve deeply into the minutiae of how all of this works.

    To repeat the writer I DON’T CARE.

    I want to check in some files, pull some files, and not have to learn all the vaguearies of a tool to do so. Sorry, I’m just not interested in that, it’s not what I get paid to do or enjoy.

    I have worked with hg a lot, and that did a really good job of handling merges, but again, if you strayed too far from the beaten path you run into alphabet soup (and honestly copying what you see on stack overflow and hoping for the best because you’re generally not paid to wade through the miasma of a VCS for hours and hours).

    And the problem is not that the tool is too hard for someone to comprehend, just once you move out of school and into the real world you suddenly have a great premium placed on your time. For me , it is that the cost of learning the tool is not in line with its benefits to me for the work I do (development, I’m not an SCM manager).

    From my point of view, a steep learning curve to use any VCS for small projects with small teams (meaning under 10 active developers) is all the indication that you need that there’s a serious problem. I think it’s a special kind of arrogance (actually the silliest kind in my opinion) that if you were just smart enough you’d understand and like it. The real problem is that it’s contribution to most is just not valuable enough to delve any deeper into than the absolute minimum. It’s a poor tool, it displays the complexity of its most intricate use cases as an interface to its users on the simplest of use cases.

    Poor design.

  124. Basic operations that are easy in every other VCS I’ve used are surprisingly difficult and unintuitive in git. If that alone doesn’t make you pull out your hair, as an added bonus, git gives you the power to seriously screw up in more mysterious ways than you ever imagined were possible.

    It certainly lives up to its name. From the Dictionary app on my Mac:
    git |gɪt|noun Brit. informal an unpleasant or contemptible person.
    Examples: “that mean old git”, “a warped, twisted little git.”

    Git is an unpleasant and contemptible VCS. Linus Torvalds may be a smart guy, but he’s apparently totally clueless when it comes to creating user-friendly software.

  125. Linus Torvalds may be a smart guy, but he’s apparently totally clueless when it comes to creating user-friendly software.

    It’s true that the user interface of this other big program, Linux, had already been designed for him by a couple of certified geniuses (Thompson and Ritchie).

  126. Yes, git is a horrible piece of nerdy nightmare. But we live with it, because we have to.

  127. Git is a nightmare. I spent more time fighting conflicts than coding. Useless.

  128. As an application developer who gets paid to write java code and deliver on time, and not struggle with git, my 2 cents
    – No good IDE plugins. E-Git has a long way to go.
    – Inconsistent command line.
    – No good free GUI (sourcetree shows promise but looks cluttered).

    95% of the times, git works just fine.

    When git messes up, there is no fixing it in less than an hour. As a precaution I have a script to zip my working directory and copy it to another folder. If git messes up, and I have to recover, I simply clone to another folder, unzip the backup in another folder, and merge manually using winmerge or beyond compare.
    Creating a personal dev branch from a team feature dev branch (which in turn is branched off from master) does not help much in such cases.

  129. Linux needs a good, hard hoof in the sack for foisting git upon us. The most complicated, hard to use, poorly documented tool I’ve had the misfortune of using. Clearcase and MKS were easier and offered up more useful features! handling compicated stuff? Bah… I had a case today, where I had a file that git thought was modified, so it wanted to merge it. Of course, it could n’t sort out that change A should be replaced ith change B, so it marked it as conflicted. Fine, rm the file and git pull. Conflict. git reset –hard HEAD and git pull.. conflict. WTF? Thanks to the suggestion above, I convinced git to just feck off and just give me the latest from the repository. Pain in the arse!

  130. “perfection is finally attained not when there is no longer anything to add, but when there is no longer anything to take away”… a superb quote that for me, sums up completely why git is garbage and svn is king.

  131. Git seems like a complete waste of time. My partner really wants to use it even though I’m the guy doing 95% of the programming, neither of us have much experience with it. When compared to my current workflow, all I am seeing are limitations in GIT and real slow downs in the workflow. For example, Bitbucket provides an issue tracker, or what I call an action items list. Yet they assume all projects are equal and all projects need only the fields that Bitbucket feels we should have… why would I not use excel instead of Bit Bucket? One example is % complete, there is no way to track this in bitbucket. Another is predecessors and successors (e.g. task a can’t start until its predecessors, task b and c, are complete). Why would I give up this system that works for everything from a small programming project to building a nuclear power plant, for something so much more restricted?

    Proof is in the Pudding:

    I also gave my partner a case study, I said ‘if bit bucket can do this, then you would have proven the potential usefulness to me’; however, he did not know the solution. Here is the case study: You have a software train without branches… you fork the code and create a light and enterprise version…a year goes by with further development on each train (say the enterprise version has 25% more code)… now you have to modify the same code in both trains… for simplicity, say the files are different but the areas being modified are not. How do I do this with a few mouse clicks using GIT? What advantage is there over using, say, winmerge.

    Additional overhead:

    Permissions seem to be a pain. No one should be merging anything without my review anyway (conventions are important, and no one currently knows them but me)… With my current workflow, I have the needed control… with GIT, your lead developer now has to manage permissions. Don’t get me wrong, I do fully see how GIT would be a valuable tool if I had 50 programmers under me distributed throughout the world… but it’s just me with some input from my partner from time to time. Under the aforementioned scenario, I would be a full time GIT expert, period.

    Reliance on third party tools: From what I can tell… GIT is really a command line tool, it’s really all the third party tools that make it useful. And yet, every single one serves a function that I already have on my desktop… I really don’t understand why people would use it for commercial software… I mean seriously, if you can’t keep these issues in check manually using traditional tools, like folder structures, then you shouldn’t be trying to automate said process.

    Lack of usefulness (integration wise): How do you use this to securely distribute updates to 10,000 customers… does it have license management? I’ve heard good rumors that GIT can help with this, but I have yet to see anything working.

    Security: Of course, I don’t like the idea of putting commercial source code on the internet even worse on a cloud. I understand you can click private, but I know security is more complicated than that. Would Microsoft and Apple put the fully formatted source code to their OSs on an online server? I don’t think so. Trust me I know code is never safe, It’s just a another risk without much of any benefit to me.

    So, that’s why I think I should not use GIT (bitbucket specifically)… am I wrong?

  132. Well, to be fair to git, very few of your complaints seem to really be about it, but able third-party add-ons and services. Nothing obliges you to use BitBucket, or indeed any publicly visible server. Just keep your git modules on a private server instead. (That’s what we do with most of our code at Index Data.)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s