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.