> Number 1-5 are mostly "I don't want to learn new things"
Git has a lot of wonderful properties, but it has horrible usability. Things like rebasing, remote branch tracking and push/pull, merge conflict resolution, stash management, and reverts are straightforward concepts! Once you grasp the concept of distributed VCS, those things should be a joy to use. But the standard Git CLI and most interfaces to it basically just drop everything on the floor and tell you to sort out the mess yourself as soon as something non-trivial happens.
This learning curve has no reason to be so steep. There need to be clearer explanations, better discoverability, and better interactive modes for all of the things I listed, and more. Telling people to RTFM just misses the point.
This is not to say that the OP makes a particularly coherent point. Just that the overall sentiment has merit.
To be fair, most of these "git sucks" posts in the past have been people moving from svn and complaining that git doesn't do it the Right Way(tm) "like svn does." In most of these cases, it has boiled down to:
1. I tried to use git like svn without attempting to do much learning at all and it bit me in the ass.
2. svn does things The Right And Only True Way(tm) and git doesn't, therefore git sucks.
3. svn has a command named 'svn <action>' and git has a command named 'git <action>' but they do different things. Therefore git sucks because (obviously) svn has the One And Only Correct Definition of <action> that 'makes sense.'
The other arguments amount stuff like:
1. I use mercurial all of the time and I don't understand how anyone can use git because of <filter-branch | commit --amend | rebase --interactive | etc> that allows you to rewrite commits. If people are allowed to rewrite commits, then obviously all developers using git do things like rewrite the X year-old commit that introduced the bug rather than creating a new commit to fix the bug. <Here is where I continue to rant about how scary the ability to rewrite commits is while demonstrating that I have little to no actual experience with git, or a single bad experience that I'm extrapolating from>.
In general, I find that I can empathize with people that get worked up over "git sucks" rants, because for the most part they either make no compelling arguments, or they bury a couple of compelling arguments under a ton of unstructured ranting about strawmen.
I'm someone who is neither unwilling to learn, nor attached to how Subversion did things. And I dislike git.
Superficially, I dislike it because it seems very little thought has been put into giving it a coherent interface. TFA points out instances of this, and it's true: whether something is implemented as its own command or as a flag to another command sometimes seems to have been decided via dartboard rather than any sort of intelligent process.
I also do intensely dislike git's own man pages, which are the first thing I'd ordinarily turn to. Unfortunately, the concept of an acyclic graph has not yet arrived in that part of git.
I dislike the way git overloads "branch" with multiple meanings or, rather, forces end users to do so. Mercurial does a better job of this currently, and has built-in support for the most important case (bookmarks vs. branches, in hg's terminology).
I dislike the fact that every repository and every branch is on equal footing except for all the commands that work differently with a remote branch or require you to do extra setup before they do work.
I dislike the fact that side-by-side inspection of different branches requires me to jump through hoops, since git only wants me to see one branch at a time. SVN, for all its faults, at least got that one right -- I can actually see two different branches, at the same time, using tools that require no knowledge of anything beyond my filesystem.
I dislike the fact that even people who use git day in and day out still can't seem to agree on a workflow. And I'm not just talking about things like whether rebasing is fashionable this week, but very basic things like when and how to branch.
I also agree with the article's point about contributor workflow; git and GitHub are more complex for contributors. There's also very little that's "decentralized", since GitHub is full of canonical central repositories, which makes me wonder what we gain from pretending we're using the "D" in "DVCS".
Superficially, I dislike it because it seems very little thought has been put into giving it a coherent interface. TFA points out instances of this, and it's true: whether something is implemented as its own command or as a flag to another command sometimes seems to have been decided via dartboard rather than any sort of intelligent process.
The examples given weren't illogical. The author's examples were git pull, which he complains is a git fetch followed by a git merge... which is quite logical, given that to pull from a repository you must first fetch the files, and then merge the files into your repository.
The second example that he complains about git commit not commiting a file if it's not specified on the command line. This makes sense, as you need to explicitly add the files via git add - something the documentation makes clear. As one of the complaints is that the documentation isn't clear, I think it worthwhile mentioning that the git-commit man page specifically says:
The content to be added can be specified in several ways:
1. by using git add to incrementally "add" changes to the index before using
the commit command (Note: even modified files must be "added");
.
.
3. by listing files as arguments to the commit command, in which case the
commit will ignore changes staged in the index, and instead record the
current content of the listed files (which must already be known to git);
4. by using the -a switch with the commit command to automatically "add"
changes from all known files (i.e. all files that are already listed in
the index) and to automatically "rm" files in the index that have been
removed from the working tree, and then perform the actual commit;
The third example he used was that the shortcut for git branch and git checkout is git checkout -b. However, this makes sense because a branch doesn't populate automatically with any files and needs a checkout. Thus git checkout -b makes perfect sense.
Perhaps there needs to be a git branch -c?
I also do intensely dislike git's own man pages, which are the first thing I'd ordinarily turn to. Unfortunately, the concept of an acyclic graph has not yet arrived in that part of git.
I think some of the opening descriptions are a little terse, but not entirely sure what you mean by the acyclic graph comment... I haven't been able to find anything obvious in the man pages that references a man page that then references the original man page... of course, I might have missed something!
I dislike the way git overloads "branch" with multiple meanings or, rather, forces end users to do so.
Could you clarify what you mean? Branches have only one meaning in git!
I dislike the fact that every repository and every branch is on equal footing except for all the commands that work differently with a remote branch or require you to do extra setup before they do work.
Could you clarify what you mean?
I dislike the fact that side-by-side inspection of different branches requires me to jump through hoops, since git only wants me to see one branch at a time. SVN, for all its faults, at least got that one right -- I can actually see two different branches, at the same time, using tools that require no knowledge of anything beyond my filesystem.
Can't gitk do this? Genuinely interested...
I dislike the fact that even people who use git day in and day out still can't seem to agree on a workflow. And I'm not just talking about things like whether rebasing is fashionable this week, but very basic things like when and how to branch.
I really can't see that's a valid argument. Some folks need to branch differently than others. This isn't just a git thing, the same can occur in SVN. As has been pointed out, branching tends to be discouraged because merging can be a regular pain.
I also agree with the article's point about contributor workflow; git and GitHub are more complex for contributors. There's also very little that's "decentralized", since GitHub is full of canonical central repositories, which makes me wonder what we gain from pretending we're using the "D" in "DVCS".
I disagree. The github workflow might be a little tricky, but as has been pointed out there are other workflows possible in git. git != github!
Does it? Pull and then merge is a common operation; it gets a top-level command. Create a new branch from the one I'm working on and check it out is a common operation; it gets a flag on an existing command. What logical, coherent process decides that in each case?
Branches have only one meaning in git!
Hence the "forces end users to do so". There are two very common ways people use branches: one is as a temporary place to do a quick bugfix, the other is as a long-lived place to do a major rewrite or refactoring. With respect to the history of the codebase, these have very different implications, but semantically are the same type of thing in git.
To pick on Subversion: when you had a long-lived branch in SVN, sooner or later you'd merge it back into the mainline... and then what happens? You want someone to be able to look at the repository and see that something major happened here and easily watch the progress, but you also want a way to say "this is done and merged". This required inventing a convention to indicate that -- in SVN, typically the finished branches would go in an "attic" directory.
In git you face the same problem: making a temporary branch, doing the work, merging and then deleting the branch is what you're supposed to do in git. But for those long-lived major branches, you need to invent a convention (commonly, tagging the merge point) to indicate that they're done.
I mentioned Mercurial because it has two different concepts for these things: the ephemeral deleted-once-it's-done line is a bookmark (which is pretty much exactly equivalent to a git branch, in that it's a named head that moves as you commit), and the long-lived major branch is... a branch. Which has additional semantics to indicate things like being finished.
This means that in Mercurial you don't have to invent and re-invent ad-hoc conventions to handle common development patterns, while in git you do.
Can't gitk do this?
Every time I say I want to see two branches side-by-side without invoking the VCS, someone says "well, here's a tool that invokes the VCS to do that!" Which shows a lack of reading comprehension.
Some folks need to branch differently than others.
Sure, but why isn't there a clearly-documented "most projects will get along fine with this" workflow? Or, rather, why are there dozens of them? We've had VCS tools for long enough that the best practices for common cases are out there.
The github workflow might be a little tricky, but as has been pointed out there are other workflows possible in git.
Oh, there are. But git + GitHub has been relentlessly hyped as an Oatmeal-ish fantasy of unicorns farting rainbows onto a field of lollipops, so that's how people actually end up using it, and so it's valid to mention that it's a more complex workflow for contributors since it is a very common case and becoming more common.
Every time I say I want to see two branches side-by-side without invoking the VCS, someone says "well, here's a tool that invokes the VCS to do that!" Which shows a lack of reading comprehension.
I'm guessing you check out a branch to a particular directory, and another branch to a different directory, then do a compare?
You could create a directory, stash you uncommitted files, then checkout the branch ad do a recursive copy to the directory you want to do the compare in. Then rinse and repeat for the next branch. After this checkout the original branch you were working in and retrieve the stash.
I'm not necessarily asking for solutions at this point; I'm asking why the "solutions" involve jumping through so many hoops to work around the VCS in order to do something incredibly common.
svn co remote_repo_path/branches/bugfix bugfix
git clone -b bugfix ./local_repo_path bugfix
It could be simpler if you removed the trailing target folder name (but git would name the checkout according to the repo name, instead of the branch name).
Joel Spolsky had the same concerns about Git when he first started using it. He changed his mind and wrote a great post on why distributed version control is way better than SVN.
It's a pretty good tutorial. But to me the mere fact that there are so many posts on How-to use a tool that is basic in a programmers arsenal, tells me that DVCS are a solution that lacks usability.
I tried Git but failed miserably with it. It could probably be attributed to the lack of quality tutorials at that time. I then thought, "Fuck it, let's try Mercurial" and stumbled upon hginit. That is one awesomely written tutorial. I use mercurial for my programming needs and find it totally intuitive to use.
I definitely found it easier than git, but that could be possibly chalked up to my bad introduction to git.
Personally, I think anyone familiar with cvs or svn can pick up hg really easily. The commands and concepts in hg map onto equivalents in cvs very nicely. My mental model of hg is just cvs + cvsync. Done.
git does not work like that. It's like each command was cut in half and recombined differently, like interlaced video or something. It's all there, it's just harder to recognize.
Hmm. I can't really comment on that since I've never used SVN. I was kind of lucky to jump directly into DVCS. The reason why I'm comfortable with Hg is because at the initial/first step the only commands I was told to remember (by hginit.com) were `hg commit` and `hg init`. Slowly, from there I took on a steady pace and grew comfortable with it. Currently on Windows I use tortoiseHg and bitbucket (I'm strictly a hobbyist coder only).
When I tried to learn Git (before Hg), I looked for tutorials but everything was all over the place and maybe they introduced too much too soon. Anyway, at the end of the day I find Hg good enough for my usage - init, commit, push, pull so far.
We are talking about programming tools here, not tools for home kitchen chefs to track their recipes. A little intelligence and hard work on the part of the user is expected.
No that's just programmer masochism. If a tool is easy to use, then I get whatever I needed it for done, and done quickly. I can then move on to doing more interesting things (e.g. programming) rather than wrestling with the tool.
Because it does not follow that if you are intelligent then you will not have to do any hard work.
Edit: appear to have annoyed someone with that comment! But do go on - prove to me how high intelligence means that you don't need to do hard work, which is the proposition of the OP.
I think his point was that software should be designed so that if someone is intelligent, they won't have to work hard (remember, "hard work should be unnecessary", em. mine). But he optimized for pithiness over clarity.
What on earth are you talking about? Git currently requires intelligence and hard work to learn properly. Regularfry suggests that we shouldn't need hard work to use a version control system. This statement isn't a proposition on the human condition, and doesn't need any proof.
Actually, I disagree. It took me no more than about half an hour to understand and use git properly. I don't particularly consider it to have been hard work.
As for it not being a proposition on the human condition - I mistook what he was saying, but then after it was clarified I understand what was meant. It was unclear to me what was being said - interestingly enough, that is the entire argument being expressed for the reason why git is "hard work".
You seemed to. You said "intelligence can be expected. Hard work should be unnecessary". What did you actually mean? I apologise if I misunderstood what you were saying!
I'm saying that while it may be valid to assume intelligence on the part of your users, that doesn't make it valid to make them work hard. I'm not saying that intelligence gets you out of hard work, I'm saying that it shouldn't necessarily get you into it - and from where I'm sitting, git requires both where it should only require one.
Really? How many how-tos are there on text editors, programming languages, build systems, deployment systems, unit testing frameworks, frameworks, APIs, libraries, debuggers...?
The thing that people need to get through their head is that distributed version control is a whole different concept. There are some things it is great at. There are some things it sucks at. Centralized version control is great at some other things, and lousy at some other things too.
I am thinking for example that if you are going for a PA-DSS-certified application, git, particularly with the ability to rewrite history, is going to be a problem, but dvs generally will provide more problems in assuring the auditor that you can locate, trace, and take corrective action if someone introduces a security issue (perhaps intentionally) into your application. I don't see git really working in that environment.
On the other hand, if you have a lively project that everyone is experimenting with and you need to merge patches occasionally to create a stable release, yeah, it's much better.
For any given project, no matter how distributed the development, you will have a "blessed" repository, from which the official releases are made. The history of this "blessed" repository is made not rewritable, even if anyone can push new stuff to it. The config files and hooks can be made writable by only admins.
Or you use a maintainer model, where the "blessed" repository is not even pushable. A maintainer (or a group of them) chooses what he merges in.
I use mercurial all the time even when I am forced to interact with git projects (thanks hg-git!) and I have no problem with rewriting history. What I do have problem with is atrocious CLIs that require you to remember cryptic incantations to do the simplest things. Two anecdotes:
- Colleague #1 has become sort of comfortable with git but only after heavily customizing gitconfig and setting up a dozen or so aliases for the most common commands.
- Colleague #2 is a devops, lives and breathes inside the command line, and still uses a GUI instead of the cli for git.
So you have had good luck with hg-git, then? Does it play well with github?
I've read mixed reviews... I'm OK with git but am deeply displeased with how difficult the learning curve is for a casual user. I'd much rather that Mercurial won.
Here's the thing though. I have been using SVN for years and am not learning Git. For a long time I figured I was just disoriented and eventually it would come. Now I am less convinced. The article really described my experience pretty well to the point where I am thinking the only sane way to use git is along with subversion.....
In essence, the more I learn, the less I like it, and the more convinced I am that it isn't what I need right now. Building accounting software there are certain things I need in a revision control system. These are:
1) revision control as audit trail. I need to know who committed a change and I need an audit trail on that. SVN isn't perfect here. I'd like to be able to audit changes to commit logs too, but that's pretty minor stuff.
2) collaboration among a smallish number of committers (right now maybe 4 active at any given point in time).
Folks have pushed git because it makes it easier for users to share modifications with eachother. That's fine, and it's a good point, but it isn't worth getting rid of a clear and reliable audit trail in order to achieve. To this end I suspect we are more likely to pursue a hybrid solution with all the complexity that provides (and indeed it is already partly implemented) than a pure git solution.
Allowing rewrite of commits is a problem not because developers might do it but rather because you can't show that developers didn't do it. If there is a question about whether a security issue was intentionally added to the code or not you need to have a clear audit trail. A basic principle of any audit trail is that your audit trails may not be overwritten.
Git version numbers are actually SHA1 hashes that are based on all the files and the entire history of the project up to there. If you modify the history in any way, then that will be a new version number and you know something has changed.
You can optionally GPG sign a commit/tag which, again, will be invalid if any part of the history is changed.
Just require commits that are signed off with GPG keys. Then you have a clean, verifiable audit trail through git. Beyond that, you'll have the full development history on your machine, which they can't just arbitrarily change.
Less, managing two version control systems seems like insanity (speaking as one who's had to do it in the past). Having people sign their commits is dead simple in Git, and you could setup hooks to make sure every commit is signed before you accept it.
This actually is the usage scenario for which Fossil[1] was created (in fact DRH made it to be in accordance to some aviation industry norms, don't remember details). Furthermore, one of the ideas behind Fossil's design was to minimize the learning curve for someone who already knows SVN.
Disclosure: I occasionally committed something to Fossil.
Git has a lot of wonderful properties, but it has horrible usability. Things like rebasing, remote branch tracking and push/pull, merge conflict resolution, stash management, and reverts are straightforward concepts! Once you grasp the concept of distributed VCS, those things should be a joy to use. But the standard Git CLI and most interfaces to it basically just drop everything on the floor and tell you to sort out the mess yourself as soon as something non-trivial happens.
This learning curve has no reason to be so steep. There need to be clearer explanations, better discoverability, and better interactive modes for all of the things I listed, and more. Telling people to RTFM just misses the point.
This is not to say that the OP makes a particularly coherent point. Just that the overall sentiment has merit.