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 hginit.com, 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).

182 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:

    http://www.lostechies.com/blogs/derickbailey/archive/2010/02/03/branch-per-feature-how-i-manage-subversion-with-git-branches.aspx

    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. 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.

  10. 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: http://www.youtube.com/watch?v=4XpnKHJAok8
    I think it makes sense.

  11. 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!)

  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. 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.

  15. @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?

  16. 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.

  17. 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?

  18. 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.)

  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. 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
    http://soberbuildengineer.com/blog/2007/04/version-control-system-shootout-redux-redux/

  24. 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.

  25. 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.

  26. 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.

  27. 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.

  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.
    Waaaaah

    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.

    http://steve-parker.org/articles/others/stephenson/holehawg.shtml

    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. attosecond

    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

    http://sigtrap.wordpress.com/2010/04/22/tortoisegit-round-2-fight/

  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. 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.

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

  44. > 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.

  45. 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.

  46. Mike,
    Please take Rob up on his offer:
    http://twitter.com/robconery/status/13896524919
    and
    http://twitter.com/robconery/status/13896675419

    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

  47. “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 :).

  48. 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.

  49. “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.

  50. 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!

  51. 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”.

  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 (http://yehudakatz.com/2010/05/13/common-git-workflows/), 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: http://www.newartisans.com/2008/04/git-from-the-bottom-up.html. 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. 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: user.name@company.com-20100506103740-3vgb1kjjf9cu6jxw explicitly tells that commit was done by “user.name@company.com”, commit time is 2010/05/06 10:37:40 UTC. Quite plenty of information.

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

  61. Clinton R. Nixon wrote:

    I hate to say “read this 31-page PDF”, but seriously, read this 31-page PDF: http://www.newartisans.com/2008/04/git-from-the-bottom-up.html. It changed me from hating git to understanding and still hating git.

    LOL!

  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 http://yehudakatz.com/2010/05/13/common-git-workflows/comment-page-1/

    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 GitX.app. 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: http://www.stevestreeting.com/2009/09/28/early-stage-gitmercurialbazaar-evaluation-thoughts/#comment-259062 and http://www.stevestreeting.com/2009/09/28/early-stage-gitmercurialbazaar-evaluation-thoughts/#comment-259056.

  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: https://lists.ubuntu.com/archives/bazaar/2009q4/063509.html. 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 http://hginit.com 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:

    http://blog.jordanterrell.com/post/Favor-Concepts-Over-Commands.aspx

  80. Josh Jensen

    Douglas: FWIW, msysGit (http://code.google.com/p/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:

    http://hg-git.github.com/

    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: http://github.com/schacon/hg-git/issues#issue/45
    … 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 (http://monotone.ca) – 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 — WordPress.com

  92. Pingback: Top Posts — WordPress.com

  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…
    Martin

  98. Josh Jensen

    Kevin:

    >`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
    +1

    @op
    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.

    Eric

  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. Gerry Beauregard

    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.)

  133. Just learn git and found this is counter-intuitive

    [xiaobai@xiaobai pika0]$ git ls-files -s
    [xiaobai@xiaobai pika0]$ git -s ls-files
    Unknown option: -s
    usage: git [–version] [–help] [-C ] [-c name=value]
    [–exec-path[=]] [–html-path] [–man-path] [–info-path]
    [-p|–paginate|–no-pager] [–no-replace-objects] [–bare]
    [–git-dir=] [–work-tree=] [–namespace=]
    []

    And i’m still looking how to undo reset blob(not commit) after spends hours of Google/SO

  134. WOW! About 6 years passed since you published this article and it’s still actual. Came across this post when we were discussing SVN upgrade and possible migration to Git for our team recently. It seems to use that your critique is kind of fair and stands with http://stevebennett.me/2012/02/24/10-things-i-hate-about-git/ and http://svnvsgit.com

    You know, we stumbled upon similar problems with Git. When we upgraded our SVN server and clients to some newer version we also discussed that we should migrate to Git and we actually tried Git for one of our new projects. Read all those guides, Pro Git, Think like a Git etc and the experiment failed. We were pretty like this picture: https://xkcd.com/1597/. It was like “WTF why do I have to run all these low-level commands for some basic operation that SVN does in 2 or 3 commands?”. We encountered the same conflicts (yeah, Git doesn’t solve conflicts by itself :))) BTW.

    So me and other our team members we do NOT understand all this Git love. Yeah, this is the hacker’s tool that seems to work well. It provides local repos! But it is too complex for daily work of a 20 ppl shop of guys with different level of expertise (from junior to 80lvl wizards actually). But there is SOOO much love for Git on the web, it looked to us that Git will solve all our problems at once (that we won’t ever need to write a string of code anymore, Git would write our code by itself!) But unfortunately its not the case. :(

    Maybe we will try Git again, but right now we are going to check Mercurial. Some of us simply need to have a local repo on a laptop from time to time.

  135. No one seems to have offered that git makes the entire archive available to the user offline. It is pretty powerful to not have to rely on a connection to a server to be able to get anything from the archive. The complexity of the user interface seems to be directly related to supporting this feature.

  136. I think that’s a given, Bill. There’s no doubt it’s the killer feature, and it’s the reason why I do use git for my own projects rather than CVS. But this feature exists in all distributed VCSs — in fact, it’s pretty much what makes then distributed VCSs. My understanding (without the benefit of first-hand experience with either) is that Mercurial and Arch are rather less horrifying than git.

  137. Bill, it was not immediately clear to me that you get a clone of the entire repo with git. So I researched it and found this discussion: http://stackoverflow.com/questions/67699/clone-all-remote-branches-with-git. In brief I guess you do get all the branches but to use them you have to figure out which one of the dozen ways is right for your situation. I imagine this flexibility is very powerful for those who need it but reading through that page made me more appreciative of the relative simplicity of fossil. Clone and open and then all branches are available unambiguously with a “fossil co branchname”. Do an update and commits made by others are immediately available for me to switch to. For those of us who don’t need the power and flexibility something like fossil sure seems a lot less cognitive burden.

    Distributed is great, but the burden of managing it in git seems higher than it needs to be, at least for most folks. The fossil approach provides you with a user experience similar to svn but distributed. I think some of the other DSCMs likely make a similar pain-power trade-off.

  138. totally agree with your post – git took a pretty good concept to make a horrible monster out of it.

    bad syntax, bad separation between plumbing and porcelain, unintuitive or misleading commands, inconsistent commands, non symetrical commands, collision one command for few things and few commands for one thing…
    and every concept drags another one in order to fix a simple case where there should be no problems in the first place…

  139. “Every concept drags another one in” <– That's it exactly!

  140. Andreas Mohr

    @Antti Aro
    “Some of us simply need to have a local repo on a laptop from time to time.”

    Then for those cases simply(? – more or less…) use git-svn and be happy.
    No need to convert the entire repo core itself to another (and potentially overly incompatible!!) SCM (aka “no need to throw out the baby with the bath water”).

    Why not stay with tried-and-true SVN base standard protocol (which might actually be a hard requirement for older / less flexible software such as EDA) for most purposes and simply let people who are more adventurous (intending to use “more advanced” tools such as git or Mercurial) “adapt” to that?

    That’s at least my thinking after having spent a rather very large amount of SvnBridge development efforts.

  141. I still manually backup the source folder, before running any operation that involves the remote repository. Git can mess up in many ways, as I have learnt over the years. I simply want to not lose my efforts.

    When git auto merges , there is no surety that the resulting output will be logically correct, even if it builds fine.

    Relying on git auto merge is foolhardiness.

  142. Stephane Aubry

    I used rcs/cvs for 20 years. I invested a total of 10 minutes learning both. The transparency of that model more than than makes up for whatever missing features it may have.
    My life changed when git was foisted on me. Hours of frustration, endless discussions with git-savvy colleagues, and the fear of a file conflict have taken their toll.
    Before git, checking files in was like opening a door, turning on a tap, or punching a phone number. It was obvious, did not need learning or thinking, and in the odd chance you screwed up, it was immediately obvious what you did wrong, and how to fix it. [CV,RC]S let me concentrate on the harder part of my job, namely writing code.
    Open source is becoming an ever-increasing part of the programming landscape, and I can see how git can add value, with its emphasis on performance, reliability, change encapsulation, and rollback.
    For other contexts, it is just plain wrong. Insanity can only last so long, and I believe it will eventually be accepted that this hammer cannot be used on non-nails, or more to the point, that this Formula 1 is a pointless tool if you just need to cross the street.

    I thank you for expressing how I feel much better than I could have. Indeed, in order to intelligently critique git, you must have enough proficiency in it to understand and know the solutions to the cryptic errors it spews out, which often means that you have invested enough time into it to feel part of the priesthood. I have not, and I will not. Unlike say C++17, which is hard because it solves hard problems, git is hard but solves problems I never had. In fact, the only problems git has solved for me are git problems. Thats a definition of incest.

  143. Thanks, Stephane. I think the fairest thing to say about git is that is hard to use because it solves genuinely hard problems — but most of them are problems that only Linus Torvalds has. Which is perfectly reasonable: he did write it to solve his own problems, after all. In the nearly seven years since I wrote this post, I have to some degree become reconciled to git, or at least resigned to it. But there are still plenty of straightforward operations that I have to look up every single time. For example, who would ever have guessed that to delete a remote branch you do

    $ git branch -r -d origin/BRANCH
    $ git push origin :BRANCH
    

    ?

  144. @Mike Also, you don’t have to do that first step to delete a remote branch, just the second one. If you think about it, it’s actually quite intuitive, though maybe not at first: Similar to `git push origin onebranch:anotherbranch`, you’re pushing “nothing” onto :BRANCH on the origin remote. This makes perfect sense, really, though it’s not obvious to newcomers

  145. I wasn’t able to complete the entire comments section because I don’t have 12 hours, but I think there are some pretty useful summary points in there. I would say with a proper understanding of HOW git works and WHY it works the way it does allows you to get into less trouble, and thus use fewer commands to fix things. My common workflow uses probably fewer than 10 commands, with very simple syntax. It may give you a shovel to dig yourself a hole, but it also gives you a really nice extension ladder to get back out of it as well.

    Your refusal to use branches is pretty asinine, in my opinion. That’s one of the git fundamentals, and it’s well advertised that life sucks without them. My opinionated use of git includes the basic tenet that one should NEVER commit to master, unless they’re feeling really really cocky, love telling teammates how to reset to origin/master to fix your mistake, or if you really love revert commits. If you’re spending longer than 5 minutes on master, you’re probably using git wrong.

    You’re a developer, man. You don’t sit down to a new language, refuse to use it properly, and then sit there any yell at it for your own incompetence, I’m not sure why you would do that for git…. right?

  146. Hmm. I am … not wholly convinced. Also, I welcome the news that git branch -r -d origin/BRANCH may no longer be necessary, but I am pretty certain it used to be. I do agree git seems to be slooowly moving towards being saner.

  147. If you’re spending longer than 5 minutes on master, you’re probably using git wrong.

    See, this kind of thing is exactly what I was talking about. It is not the job of a tool to dictate how I work, but to work for me. I use it, not the other way around. It may or may not be the case that for my specific project, with my specific collaborators (or lack of them) working directly on master is the right thing to do. That is simply not something a toolset should have an opinion about.

  148. @Mike I can agree with that, but those opinions are really for your own good, and the whole reason git was made the way that it was. I’m not saying you can’t do it, but you obviously needed knowledge of `git pull –rebase` because your way of working with it mandated you do so.

    I just don’t really understand why would one want to spend a bunch of time working a feature on master instead of taking 3 seconds to create a branch to keep your workflow clear. This works hand-in-hand with pull requests as well, so everyone can see everything that you did in one place without having to hammer out a complex diff in the command line using SHA references. And if you’re not working with collaborators, then working on master is truly a non-issue, except that you can’t really squash/fixup without force-pushing to the remote when you’ve decided to rewrite history. Branches were specifically designed to allow these things.

    It sounds like you have a good handle on it, really… many of the commands you’ve used I’ve never had to, and I’m just opining that you’re fighting an uphill battle just to avoid using branches.

    Sorry to necromance, just seems like this is still pretty relevant, despite the amount of time that’s passed :-)

  149. Necromancing is always welcome on this blog — some of the most interesting comments I’ve seen have been on long-ago posts, and I always see every comment.

    I admit I am intrigued by your picture of a radically different way of using git. I freely admit, too, that having come to it via SCCS, RCS and CVS, my model is a probably inappropriately monlithic one. I really should one day get around to watching that Linus video.

    BTW., if you’ve not yet seen this followup, I think you will enjoy it.

  150. Pingback: What I’ve been reading lately, part 21 | The Reinvigorated Programmer

  151. git is an evil waste of time. It is not a tool, but rather a “religion”. It is popular because it’s “free” and every third world country has access to it but it is not “free” by any means when you count the thousands of man-hours being wasted by experienced people trying to do the simplelist things. If I want to roll back a single file out of ten-thousand to a version four checkin’s ago – In Perforce you right-click the version and select roll-back – click done…. Can you do this in git? I’m sure if you’ve wasted hours of your life learning this mean and terrible succubus then maybe that’s no problem for you, but that’s not 99 percent of the people out there. You have hack git! You have to sneak up behind it and slit it’s throat, because if you don’t attack first, you will surely be bent over and raped … repeatedly! The goal of git is to create elitist who have no lives and end up selling their souls to Satan for “special git powers” which allow them to look down their snide noses and suggest “well all you gotta do is the ctrl-backspace-double-flip#75674367554-1.1.1.33333 command – geez everyone knows that…” – The ultimate goal of git is to completely destroy all productivity by making work not about the product, but about the source control….. all praise be to git holy of holies!!!

    Just because something cheap and popular DOES not make it better – Can you say “Welcome to Walmart!”???

  152. Well, honestly, I can’t say I agree with you. Git is flawed, but doing a good job overall.

  153. Do you not see what is inherently wrong with this thinking? Would you say “well my doctor is flawed but, he hadn’t killed me yet ? ” – why would you settle on such a silly compromise. Engineers typically demand the best of their toolsets. They understand that nothing is free and in many cases you get what you pay for. Having a tool that demands such a vast knowledge to do the simplest things, is difficult for most and is tedious at best is no deal. And the fact it requires endless hacking and Google searches to do relatively simple tasks is further proof this is a time wasting toolset which detracts from what should be most important – product development. Notice I didn’t say “Programming” – because over the years it seems that many new “engineers” have turned programming into the end goal, rather than as a means to an ends. git comfortably adheres to this philosophy….

  154. @BadRoy So you want your cake and to eat it too? Your example with perforce described “right-clicking”, which tells me you’re using a GUI to make these changes. There are literally hundreds of Git clients out there you can use to be a lazy developer, why don’t you try one? What I think Git did really right is almost provide a low-level API to allow powerful, high-level tools to provide feature-complete functionality, but it’s also easy enough for MOST OF US to use in the command line. Honestly, if you stick to a consistent workflow, you only really need the commands add, commit, branch, checkout, rebase, diff, and push. I know many more, but I seldom have to use them.

    We’re not in software development because it’s easy, after all. I’d suggest you stop complaining about a tool no one is forcing you to use, and also learn how to use your tools instead of fighting and complaining about them. There’s a reason Git is so popular, and it’s not [just] because people want to show off.

  155. BadRoy,

    Do you have any idea why it is that the great majority of the software development community is unable to see what you see so clearly?

  156. Yes I do. Here are the primary reasons;

    1. It’s free to download and to use and so every third world developer has access to it.

    2. Because of it’s legendary cryptic nature, it’s become a sort of adolescent “coolness” test, as in “oh you have to be smart and really cool to use git…. you old people just don’t understand ….” – it’s cult. This greatly appeals to the anti-establishment group and younger inexperienced programmers to feel like that now have some greta and mysterious advantage over older, more experienced programmers.

    But free does not implicitly mean better – it means a lot of poor developers have had to learn to this tool because they could not afford to shop around and see better alternatives.

    And the notion that something is better because it’s hard to use and cryptic is nonsense. Furthermore, these are not just my opinions, search the internet. The “emperor has no clothes” movement is afoot. More and more young people are are being put into positions where they no longer have time to make a career in source control, but rather must not deliver real products are quickly coming to this conclusion.

    One example is a young girl from India I know. She’s very smart and has worked at several companies using git and perforce. When some people at our company tried to force git down our throats, she told me she hated going back to git; that while git was all she had ever used or knew growing up in India, once she worked with Perforce she never wanted to go back.

    Further reading :

    https://ohshitgit.com/

    GIT: a Nightmare of Mixed Metaphors

    Don’t use Git

    I could add to this endless list – a simple Google search should be enough to convince any practical programmer – git is a nightmare.

  157. And the notion that something is better because it’s hard to use and cryptic is nonsense.

    Well, of course it is. That’s why no-one believes it.

    In the world of software, freedom means much more than not paying money. It means ubiquity. Your Perforce repository is of no use to me, or to six billion other potential developers. But they can all use my git repo. Don’t underestimate the power of that.

    I’m not really here to defend git: as should be apparent from the initial post, I’m well aware of its flaws in concept, in implementation, and in community behaviour. But I think we have to accept that it also does a lot of things right, and hasn’t attained its global pre-eminence either by accident or due to a conspiracy.

  158. Just like Walmart….

  159. The Walmart analogy doesn’t work because there’s no network effect. If another cheaper shop opens next door to Walmark, I can do there instead. But if another, objectively better, version control system pops up alongside git, I can’t just switch because all my friends and colleagues are using git.

    (And by the way, it’s worth noting that CVS held that lock when git came along, and git offered enough steps forward to break that lock. It was evidently doing something very very right.)

  160. “if another, objectively better, version control system pops up alongside git, I can’t just switch because all my friends and colleagues are using git”

    Yes, the ubiquitousness of git is another hideous aspect of this destructive virus… Luckily many of us who do high-reliability, safety critical programming aren’t shackled to internet downloaded code which is strictly forbidden in 99% of safety critical applications since you really have no clue what you’re downloading and none of it has been certified.

    I’ve used numerous source control applications over the years, both centralized and decentralized (and yes I’ve even had to use CVS previously), and I use git now in some areas for the very reason you point out …. like you, I have no choice. But perhaps unlike you I will not go gently into that good night – join the revolution my friend! Maybe if enough people stand up and admit that they all have horror stories to tell, the git people will improve it to the point where it becomes a solid product which doesn’t require either the user be a plumber or a priest to use… Don’t get me wrong, if git was user friendly to the point where both older programmers and new kids on block could sit down and just use it without the sword of Damocles hanging over their heads, I’d be git’s biggest fan. As it is, there’s not one programmer I know who can’t tell you about that time git wiped out a week’s work or worst destroyed other people’s work…

    Come on – we can do better than this!

  161. Brooooo, you’re killing me here. There’s nothing wrong with git. If you don’t like the CLI, then use a GUI. If you don’t like git, then don’t use git. 99% of us don’t have a problem with it. Of course people have horror stories with git, as they do with any complicated technology. And that’s exactly what it is… This is a complex problem that requires complex solutions, and the level of abstraction for that complexity is up to you. That said, we do what we always do… learn and move on.

    Feel free to tell Linus (e.g. “The Git People”) that he should “fix git”, and I’m sure he’ll free to call you a “fucking idiot”. Your complaints just don’t have any perceivable merit to them.

  162. I’m almost certain 99% of your complaints would go away if you just downloaded SourceTree Github Desktop. As I mentioned before, the CLI tool can be thought of as a low-level API, though I do use it directly 95% of the time (unless doing complex partial commits with IntelliJ, since line-level control is much easier this way). Again, though, that’s also a GUI, so YMMV.

  163. Ha! Look at the top of this page – it’s entitled “Still hatin’ on git: now with added Actual Reasons!” – and you’re irritated that I’m calling a spade a spade here – I concede that despite the near universal deep-seated, though seldom-voiced hatred for git, it’s very popular – just like Walmart – very popular – everyone loves Walmart….. but to boast this crapware as the best we do is just sad… so go ahead be a sheep like the rest of the sad git users out there…. but deep seated suppressed anger is not healthy dude!

    Also I seem to remember an interview where Linus actually apologized for git – said it was just something to use while focusing on Linux never meant to be a product.

  164. I use Sourcetree in combination with command line… no one in our group uses the same methods –
    By the way are you some kind of git representative? You seem very eager to defend this stuff…

  165. But we (I?) don’t use it because it’s popular and it’s shitty, we use it because it serves a need, and serves it well. No “sheep” would actually stick with it if it sucked at what it did, and it didn’t just get mass acclaim and hold onto market share as a result of fanboy acclaim. If you’re as technical as you proclaim, you should know that fad technologies die when the honeymoon is over. Git didn’t burn out, it became a mainstay in software development. Git allows excellent collaboration via a well-thought-out distribution scheme.
    Branching is easy and cheap, and recovery options are nearly limitless for any number of scenarios. Once you find your stride with it, it doesn’t stand between you and success unless you stick with your bad habits (e.g. refusing to use branches).

    I’m not a rep for git, I just don’t get the point of complaining endlessly about it when so many people are obviously satisfied. If you’ve found Perforce or CVS or Mercurial work for you, great, more power to you, and I wish you success. But if you hate git, then kindly leave it alone and move on.

  166. You’re shackled to it and admit it has flaws, but you’re ok with it??? (Hmmm. and not a sheep…)

    You don’t seem to be very tolerant of other people’s opinions? But from your pic you do kinda look like that Hannity guy off of Fox news, so maybe you’re a big Trump lover as well – would explain a lot , but to each their own.

    Anyway, I made comment on a board which is seeking different views and input from everyone in the community (this is a public board) and you get all up in arms – I didn’t realize that I was expected to respond in a way that aligns with your personal beliefs.

    But here’s the deal – if you’ll stop responding so will I, but I’ll not have my opinion stymied or muted by the likes of you – not everyone loves git dude – get over it!

  167. I’m neither shackled to it nor did I admit it has flaws. Don’t put words in my mouth. You’re absolutely entitled to your opinion, but your opinion seems to be “Git sucks ass and we should change it so it works for me, a person who doesn’t use it except when forced to”, which is absolutely asinine. I respect that you don’t like it, but leave it there. Don’t call for a revolution. Feel free to make a competing VCS that suits your needs if none exists. But if you’re going to keep using git wrong and think it should conform to you, I’m going to keep thinking you’re an idiot.

    I get that not everyone likes git–if you scroll waaay up you’ll see that I’m making helpful suggestions about how to stop using it the “wrong” way, e.g. committing your feature commits to the master branch and then screaming bloody murder when you have merge conflicts on pull from upstream. Of course that’s going to suck, because you’re fighting against the fundamental assumptions on which git was built. I don’t care who you are or what your opinion is–the simple fact is that if you’re using it wrong, it’s going to be a shitty experience for you, and everything you’ve said thus far seems to say that I’m right on this point.

    If your only point here is to complain, then I think we have nothing left to discuss. Also, way to bring Trump into it–I can tell at this point that you’re just trolling.

  168. Your words – not mine – “… I can’t just switch because all my friends and colleagues are using git.” and “Git is flawed, but doing a good job overall.”….

    But thank you for acknowledging other people have valid opinions that don’t conform to yours and the collective.

    You said “the simple fact is that if you’re using it wrong, it’s going to be a shitty experience for you,…” -well duh! if you’re using wrong … but what’s right? If you google you’ll find tons of people who find “using it right” unintuitive and unnecessarily difficult – but well “…doing a good job overall.”.

  169. I didn’t even say those quoted lines, last I checked, the name “Mike” isn’t the same as “Adam”.

    I would argue that if it’s unintuitive and unnecessarily difficult, you’re either not using it “right”, or you’re not using it “enough”. And as with any subject on the planet, you’ll certainly find some material on the internet that fits your confirmation bias. After all, if that’s what you’re searching for, that’s exactly what you’ll find.

  170. My mistake Adam – So to be clear, you’re saying you can move away from git anytime you feel like it and also you think it’s the perfect source control application then???? Is this correct? Oh boy –

    Not using it enough? (Not smart enough? implied) The whole point is I can go back to 30 year old applications like MS Source Safe (which really sucked for other reasons and no I’m not suggesting people use it today) but the point is I can use it today if needed without having to “relearn” it – why? because it’s intuitive – every since the idea of the gui was developed, the goal has been to make things easier so you don’t have to remember a load of cryptic command line crap. git’s command line interface (which i find is the only reliable way to use it in most cases) is going backwards…. and if you walked away from git for 30 years and went back I very much doubt you would remember how to do the simplest of things.

    I really don’t this line of debate is very useful or productive – you’ve drank the kool aid and are for some reason you’re personally offended by a difference of opinion so let’s just agree to disagree sport.

  171. 1) Yes, but why? The burden of moving is really on the destination VCS system’s ability to import my history. It’s not up to git to know how to export into some other system. But this is a moot point, and I’m not sure why it’s of concern. 2) So far, yes. I haven’t discovered any shortcomings that cause me to be upset with it. It suits all my needs, and doesn’t lack any feature I wish it had that isn’t covered by GitHub Desktop, SourceTree, Bitbucket, GitHub, or any other GUI tool.

    I’m not implying you’re stupid. If you’ve been listening, I keep referring to git as both a low-level API and CLI that powerful GUI tools can ALSO interact with. I’m guessing with Source Safe, you’re pretty much stuck with their UI or bust, whereas Git has a lower level of abstraction that allows you to either use it directly, or use tools on top of it. The fact that I can tinker with GH Desktop, SourceTree, IntelliJ, and Bitbucket SIMULTANEOUSLY speaks volumes about how well Git does this. They didn’t try to build out your entire workflow–just the basic primitives that allow you to interact with your code and history, and do so in a manner that maintains integrity of the whole system. Again, you seem to be of the impression that you’re FORCED to use the CLI at some point, which isn’t a reasonable stance, in my opinion. You can use Git all day without typing a single command, if you’re so inclined. I just find that when I’m in CLI context all day long, CLI is generally the fastest way to continue to get stuff done instead of hunting for another window to make a code push. There’s also an inherently large amount of muscle memory in doing it this way–I often find my fingers typing the commands without even thinking about it.

    There you go again with the Kool-Aid… I think I’m doing a far better job of substantiating my claims than you are, and I’m only offended that someone is offering an opinion without appearing to have done their due diligence with the obviously-steep (and fairly forewarned) CLI learning curve. Do you cry this much about every new technology when you start using it? I’m guessing not.

  172. I embrace real improvements and true advancement, and while there are some cool aspects of git, the cost / benefit for a company is not always there with git. The evidence I offer is the tons of issues found on the internet showing thousands struggling with it (i.e. hundreds of thousands of man hours of lost productivity trying to get basic source control) which don’t represent rare exceptions, but rather the general rule for git usage – it’s needlessly complicated and cryptic.

    Since you don’t find it so, then you’re obviously a super genius – but when it comes to it most normal humans end up having to google for answers to how to do anything outside their particular three or command usage paradigm.

    Also I’m a bit surprised by you’re continuous whining defence of such a product. Why would you defend with such passion so the point of using vulgarity? But to each their own.

    However, I tire of this conversation – I’ve stated my opinion, you’ve stated yours. Some will agree with me, some with you. Nothing more say really…

  173. Stephane aubry

    Well, if I can summarize the git lovers arguments, it boils down to:

    1) Git is complex because it solves a complex problem.
    2) If you have not put in the hours to understand the concepts of the tool and how to best use it, you are just a hater and your opinion does not count. In fact, your lazyness is proof you hardly deserve to call your yourself a developer.
    3) The fact that it is used by many developers proves it is a superior tool.

    These arguments are in fact pure hogwash.

    1) Source control is a simple problem. It was solved thirty years ago, and does not deserve to be an object of study. You should not need more than five minutes to master source control. In fact, most of the five minutes would be to understand why you need source control in the first place. So that leaves about one minute for the tool itself (checkin, checkout, done). CVS/RCS achieves that target. If you need more time, the tool is wrong. But somehow, the priesthood has convinced many hapless developers that _they_ are somehow deficient.

    2) The argument about “learning” is just as valid as the requirement that medieval doctors had to speak latin. Basically, impose a high enough barrier-to-entry so that only the cognoscenti can solve the problem they created and that did not exist in the first place.

    3) Git gained acceptance because it is efficient, well-suited to open-source, and written by Linus. Then it was foisted on a majority of developers by a bizarre alliance of clueless managers and no-life-nerds. So yes, no one is forced to use git. They can quit their job and and look for a dev team that does not use git, if they can find one. Should source control define one’s carrier? Thanks to the afore-mentioned alliance, it looks like the answer is yes then.

  174. Stephane aubry

    Well, if I can summarize the git lovers arguments, it boils down to:

    1) Git is complex because it solves a complex problem.
    2) If you have not put in the hours to understand the concepts of the tool and how to best use it, you are just a hater and your opinion does not count. In fact, your lazyness is proof you hardly deserve to call yourself a developer.
    3) The fact that it is used by many developers proves it is a superior tool.

    These arguments are in fact pure hogwash.

    1) Source control is a simple problem. It was solved thirty years ago, and does not deserve to be an object of study. You should not need more than five minutes to master source control. In fact, most of the five minutes would be to understand why you need source control in the first place. So that leaves about one minute for the tool itself (checkin, checkout, done). CVS/RCS achieves that target. If you need more time, the tool is wrong. But somehow, the priesthood has convinced many hapless developers that _they_ are somehow deficient.

    2) The argument about “learning” is just as valid as the requirement that medieval doctors had to speak latin. Basically, impose a high enough barrier-to-entry so that only the cognoscenti can solve the problem they created and that did not exist in the first place.

    3) Git gained acceptance because it is efficient, well-suited to open-source, and written by Linus. Then it was foisted on a majority of developers by a bizarre alliance of clueless managers and no-life-nerds. So yes, no one is forced to use git. They can quit their job and and look for a dev team that does not use git, if they can find one. Should source control define one’s carrier? Thanks to the afore-mentioned alliance, it looks like the answer is yes then.

  175. Sigh. You guys just aren’t listening.

    1) Git CAN BE complex because it is capable of solving complex problems. If you’re just using VCS by yourself, this is indeed very simple. Get GH Desktop or SourceTree, init, commit, push if you want a remote, or don’t if you just want history. This can easily be learned in 5 minutes.
    2) If you want to CLI bash, sure, it’s going to take a long time to understand. Otherwise, see point 1.
    3) Aren’t good developers inherently “no-life nerds”? Does anyone really decide that their level of development is “good enough” and quit? You wouldn’t apply for a job in Java if you’re only proficient in Python, so if git is a hard requirement, why is this any different? Or maybe you’re like the majority of applicants prepared to, you know, LEARN SOMETHING when they apply for a position, and, employer willing, that’s just fine too.

    You’re honestly blowing this an order of magnitude out of proportion. I guess it serves me right for commenting on a fucking rant post in the first place, this actually may very well be my fault.

  176. If a person has personal opinion that differs with your “he’s a hater and lazy” – Wow – this lack of tolerance for others opinions is staggering –

    Thing is I know how to use git children and I use git regularly and I can pretty much do anything I need to do with it – but it’s never easy and never straight-forward and alway frustrating and always thousands of others on the internet with the same questions.

    Well as i said, I’m not the only one who hates git or rather would appreciate improvements which would end the endless stream of questions and people who have lost code due to the unnecessary complications – so since this board is obviously intolerant of other views – I leave you to your mental masterbation – enjoy git… It’s obvious from the neediness and insecurity here I’ve stumbled into a nest of millenionals.

    And btw here is THE most useful site I’ve found on git –

    http://www.evan.org/Fun/Git/index.htm

    enjoy gang

  177. arcreativenet

    Drink much?

  178. Well, folks, this has really blown up while I was sleeping.

    First, can I ask you all please to remain civil and avoid ad-homs. I’ve often been astonished at the quality of discussion in this blog; please don’t spoil that.

    I think most of the disagreement here comes down to Stephane’s first point in his summary of git defenders’ position: “Git is complex because it solves a complex problem”. I know Stephane disagrees, but I think this is dead on. Source control was solved 30 years ago: for single-person projects, or projects with a small number of closely connected developers. I know, I used to use SCCS on my own projects before being introduced to the shiny newness of CVS. But git is doing very much more than that. It’s goal is to facilitate collaboration between huge geographically and culturally dispersed teams whose members don’t know or necessarily trust each other, in the context of products with complex branching release schedules (e.g. the bugfix release 2.5.4 may come out some time after 2.6 or even after 3.0). These are hard problems, with real inherent complexity, and it’s not surprising that the solution is complex.

    It is true that for many projects that complexity is overkill. There’s nothing wrong with using a small, simpler version-control system for a small, simple project. But once you’re used to using git for large-scale long-lived highly collaborative projects, it’s easy just to stick with it for the other stuff, too. That’s where I’ve landed up, anyway, after wrestling through my own issues.

  179. Thanks!

    I’m now more motivated to stay with Mercurial, that’s simply much more sane. Git might be useful at some point so I’ll keep an eye on Git, if nothing else because teams might ask for it, but for my own development I simply don’t need any unnecessary complexities. Setting up Mercurial took me 5 minutes first time I used it.

    I disagree that complex issues/goals must have complex solutions. Simplicity is always an option not to be overlooked. if you don’t at least strive for it you’re doing it wrong.

  180. I don’t think anyone’s said that complex problems must always have complex solutions. But anything that’s complicated is that way due to a combination of two factors: the inherent complexity of the problem to be solved, and “wasted” complexity that is introduced by a suboptimal solution. I started out thinking that git-as-solution-to-version-control was mostly the second kind of complexity. It certainly introduces some of that — not all its decisions are defensible — but I have increasingly come around to the perspective that most of the complexity is real, and inherent in the problem we’re trying to solve. That said, if you don’t need to solve the whole problem (teams distributed in time and space contributing potentially conflicting changes to a codebase that must both move forwards and maintain bugfix releases of older versions) then you don’t need the whole solution.

  181. Pingback: Revisiting my issues with git, nine years on | The Reinvigorated Programmer

  182. Pingback: Why you should never employ a techie to solve your problems!!! « Agile Insider

Leave a comment

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