`git`. I mean, its so popular that you get used to it eventually but the commands never make sense or map well to the mental model of what you're doing. And "getting used to it" is a seriously low bar for software IMHO.
Haha - I've used mercurial almost exclusively for maybe ten years, and the biggest share of my points on Stack Overflow is from a question I answered about a confusing part of git.
Git has a very clean and simple data model. Unfortunately, this nice model often has very little bearing on how the `git` CLI works; it often takes things that should be simple operations and confuses or complicates them in various ways.
For example, say you’ve just made a commit, and then realized that wasn’t what you wanted to do so now you want to undo it. This can be described under git’s data model as “set the current branch to HEAD^ and discard the orphaned commit, leaving the working tree alone.” For some reason this is a “reset” operation (the same command you’d use to unstage a file, an otherwise unrelated operation) and you have to decide if you want to do a “hard,” “soft,” or “mixed” reset. If you get it wrong you’ll have to go grovelling in the reflog to get your files back.
To be fair, this situation is improving; the recent introduction of the switch and restore subcommands has helped to disentangle the especially overloaded checkout and reset subcommands, for example. But it’s still harder than it should be to convert a mental image of what you want done into the appropriate (series of) git commands, and vice versa.
I have observed vastly different opinion of git among people for whom git was the first vs, and people who were using svn or cvs before. The former is mostly fond of git, and the latter highly critical, mostly I assume because the concepts don't map the same way.
While I myself think I am pretty familiar with git cli, I don't really use the cli anymore, since intellij covers all the features in a much more intuitive way. e.g staged edits, rebase.
SVN is so dead simple to learn and use. And while I see the benefit of DVCS it hasn't really had much impact on developer productivity. The tools around are just so much more sophisticated than what we had for SVN. And I kinda miss being able to checkout subfolders directly.
I don't champion git, but it is sort of the least worst SCM overall. I'm a graph thinker so that aspect never gave me much trouble, but the CLI is a seriously weird jungle of odd naming, based limitations¹, do-all commands with flags changing the entire command out for a different one and poorly written manpages.
I'd also like to point out that the concept of not having the history local (as in CVS, SVN and some of the still-used commercial SCMs), but only on the special sanctified server, feels seriously weird and extremely limiting to me.
¹ The by far weirdest one is --set-upstream specifically (intentionally?) not working if local and remote branch names don't match, so "git push repository branchLocal:branchRemote -u" doesn't make "git push" work if you are on branchLocal. It feels like that's half the point to have that option in the first place. But nah.
I've never had problems with git "not mapping" to my mental model of what I'm doing, so maybe you could help expand on what that means. But I've run into two categories of people that struggle with git
Novice developers that just haven't taken the time to learn more than three basic git commands. Their lack of knowledge is the problem 99.9% of the time, but they don't know enough to know they are the limitation, and they blame the tool instead
Old developers that come with a mental model of another VCS and either cannot or will not change their mental model and continue to be frustrated that they weren't consulted when git was designed
A third category may exist, but I have not met these people IRL
Supposing you have an accurate mental model of what git does, the odd thing is that many of the most common commands don't correspond to simple operations on that model.
Most notoriously, 'checkout' and 'reset' have a number of very different behaviours depending on the shape of the parameters you give them (which is why they've very recently added 'switch' and restore').
And some things that ought to be primitive operations don't seem to have any simple command at all. For example, if I have branch 'wip' checked out, and I'd like to advance branch 'dev' to point to the same thing as 'wip' without changing the currently checked-out files (even temporarily, because I don't want their timestamps to update).
And the preferred commands for managing the per-branch and per-remote push and fetch and merge settings have changed so often that I gave up years ago and just edit .git/config directly.
This. A lot of the responses in this thread seem to conflate git commands with the git idea. The idea, which is to model a tree of files as a set of objects that contain metadata pointing to content-addressable files, is a very good one. The commands are very bad.
Git tooling has improved dramatically and papers over most of the confusing parts. The biggest flaw by far is the opaque command line rules. There's a reason "how do I undo a commit?" has >20000 votes on StackOverlow instead there being like "git undo" or something obvious like that. There's dozens of Qs like that because it's so far from obvious. A lot of git purists in the early days insisted on uselessly complex workflows (rebase this and bisect that) despite adding little value. And the general concept of staging a commit isn't very useful either.
My use case is simple enough. Git provides a list of checkpoints I can rollback to. I generally squash over merge, and I use vimdiff to resolve conflicts. I know every command I need to do those things. What's complicated to learn?
For 99% of git, I'm happy with GUI tooling in the likes of VS Code, Visual Studio and Rider - it's clear, and it works great.
It's only very occasionally that I have to drop down to a command line to fix some kind of merging snafu - if that happens, I'm guaranteed to have to Google it, but at least I'm also guaranteed to easily find a solution on StackOverflow.
Yes, I used to use it before VS Code came along, and before VS improved their tooling, and before I switched to Rider. Github Desktop was probably the first good git GUI I ever used.
I've never felt that the commands don't make sense or that they don't map to my mental model. Actually I don't understand that complaint. It's not like I set a mental model prior to learning git and expect git to follow it. I base my mental model on git while learning it, so of course it's going to map it. That's what learning how to use a software entails.
If we're talking about inconsistencies in git, the only one that comes to mind is how diff's `...` behaves like log's `..` and diff's `..` behaves like log's `...`. I.e. if you want to see the changes of `git log a..b` as a single diff, you'd use `git diff a...b`. If you want to see the changes of `git log a...b` as a single diff, you'd use `git diff a..b`.
I hate the Hole Hawg story with a passion. Firstly, because it's wrong: the story say things like "it's a cube of metal" and "the handle is not ergonomic".
But look at pictures from the maker. It's not a cube, and the handle is in fact ergonomic. Indeed, I would hope that a drill used by expert for hours every day would be 100% designed to make their jobs easier, and that includes not given them crippling injuries. And it's 100% purchasable from Home Depot. And, looking on Amazon, it's half the price of a truly expensive drill.
But there's another level at which the story is bad. The story feels like a story about gatekeeping: either you're one of the special people, or you're a useless homeowner. Either you have big problems, or you shouldn't be here. Either you've dedicated your life to drilling holes, or you're not welcome.
So, I read the story, and it sounds like both an exciting story of a newbie learning that some profession has unexpected depth. At the same time, it's also a story of a person who wants to be part of the special exclusive club.
I read the story and still cannot decide if you're for or against git, because "It's so powerful that will gladly drill a hole through your wall, and even your foot, if you don't give it its full due respect" is definitely not a characteristic I want for a system managing my source code.
- I have to be a good user of it. I can get away with knowing a couple flags for these tools
- Git is inherently stateful. I can iterate on my grep-ing/sed-ing/curl-ing and try random stuff, but git operation can be destructive or leave me in a state I don't understand and do not konw how to get out of
It maps very well to my own mental model? I'm not arguing that the parent poster doesn't have the problem that they say they have, but it's a problem I do not have and haven't encountered very much with new users after explaining it to them?
I assume that people who find git extremely difficult are unwilling or incapable of learning the internal data model. I think if you want to have distributed source control, there is a minimal complexity that exists. I also previously used cvs, svn, and perforce, so maybe that affects my opinions; I strongly believe git is a huge improvement over all of the aforementioned.
Note I think git could definitely be easier to use, and the reuse of eg checkout to switch branches and revert a dirty file to either staging or the most recent commit is a bit strange. But calling it uniquely bad is silly, imo obviously.
For working software engineers, I both think -- and recommend to juniors -- they must invest the effort to learn an editor, git, and at least one language + toolkit deeply.
I think that the most important goal of our profession is to find and implement high-level concepts so that our users don't need to worry about tiny details.
As an example: when I buy a back-up hard drive from a typical brick store like Costco, the "back up hard drive" is abstracted away: I don't need to study the USB timing diagrams, or worry about the details of how the magnetic domains are imprinted on the spinning disks, or really any of the chemical details of the surface coating.
This abstracting away of details is AWESOME. I can buy a $150 disk drive after spending less than a minute considering the purchase.
Git, on the other hand...
Let me give a real-life example of where real-life git and real-life published work flows don't work: you can go into GitHub.com, and make a project. And you can write code in Visual Studio, and save it up to your new git project.
Unless, of course, when GitHub.com recommended that you add a license. The instant you add a license, the project isn't "empty", and once the project isn't "empty", you can't trivially push your new Visual Studio project up.
The fix for this is to delete your GitHub.com repo.
I bet you'll reply and say, "that's just real-world problem! I only want to hear about theoretical problems!" -- which, IMHO, is one of the problems my profession faces. Real-world problems are ignored in favor of theoretical ones.
Maybe don't imagineer what I would say based on poor evidence.
Because (1) github doing that is kind of dumb (though (1a) how often do we make new projects?), and (2) we're discussing git as used for source control, particularly the commands. That's distinct from using github as a remote.
A programmer doesn't have to know the IR (intermediate representation) of their compiler to write code and they shouldn't have to know the internal data model of git to store code.
I had this problem until I spent time to learn the underlying data structure of git. Everything pretty quickly fell into place after that (git checkout still has too many jobs IMO).
The git commands do not abstract over the internals, they pretty much just provide a direct interface to them.
The problem addressed by git or any other serious version control system is complex. Any seemingly simple solution will be severely limited, even if it does some particular things reasonably well (e.g. Subversion).
Git offers the flexibility to let each person work the way they prefer, even (to a large extent) on large shared projects.
With some wrappers and hooks, you could quite easily cripple git so as to emulate most any simple VCS. The aforementioned enterprise products barely work at all, so replicating their non-functionality might require more effort.
It being flexible is not the reason for all criticism of git, and simple wrappers don't fix all its issues. (and even if it were, "you need wrappers and hooks to work around its pitfalls" would be a completely valid criticism)