That was very informative, but I wondered if there is an easy-to-read reference somewhere about WHY git works the way it does?

I am old enough to have used SCCS, RCS and CVS extensively. Each had their faults, but Git is the only VCS I have used where dealing with merge conflicts is unintuitive enough that I sometimes end up with the repository in an unusable state. I am sure I am doing something wrong, but I would like to understand why.

The VCS that maps closes to the way my brain works is ClearCase. You essentially have a versioned file system, and you can set up a view to present any previous state of that file system. Of course, administration is a nightmare, it is not distributed, it is expensive, yada, yada. But when using it I always felt I knew exactly what was going on under the covers, which is not the case with Git at all.

I used git for years now. I’m comfortable with all of the basic functions. It is my experience that I have had several times where merging/branching has caused a repo to “break” It doesn’t happen often, but when it does it’s super frustrating and this I avoid the merging workflows where possible. I’m sure if I educate myself a bit more about git and pay more careful attention to the details, I wouldn’t occasionally have this problem, but Git really shouldn’t be like this.

Git could be a lot better in a lot of ways, particularly from a developer experience perspective. I’m a little surprised we haven’t seen a meaningful successor.

One example is how git will deceive you and tell you you’re up to date with your remote (e.g. origin/main). What it means is that your local branch is up to date with its local concept of remote, and makes no statement guarantees about the actual state of the remote. Which is really a nonsense concept that does not need to exist.

Similarly the whole concept of needing to specify “origin” at all is a bit bonkers and does no favors. Why is it that I can pull from a remote branch, commit some changes, run ‘git push’ and git has no idea what branch I want to push to. Another example: if main is a protected branch, don’t let me accidentally commit to it locally. I could keep going with the examples but I won’t.

And yeah you can forgive all this by quibbling that git was written in a time when internet access was not ubiquitous, and of course all these decisions make sense because x, y, or z advanced edge case for advanced users only, and I’m a shitty engineer because all of this complexity secretly makes my life better and I’m just too simpleminded to appreciate it.

Really though, if you rewrote git from a principles first approach (with developer experience being one of those principles), it certainly would not look like how it looks today. There is too much complexity, too many ways to do things, and too many bad decisions around defaults. Treat it like a proper distributed system, perhaps even backed by a real database. It’s not special because the data is code. The fact that it’s treated as such is the reason it feels so weird.

Git separates its plumbing from its porcelain very well. That makes all the different front ends possible. Maybe there's one that will help you to work with git?

I differ from your opinion that the user experience is poor. I think it's great, and I prefer using the command line interface.

As an example of a different frontend, have you tried "jujutso" [1]? Every time I ended seeing a comment about git vs Hg usability I am reminded of it. It uses git in the backend but its workflow/frontend seems streamlined.

  Jujutsu is a Git-compatible DVCS. It combines features from Git (data model, speed), Mercurial (anonymous branching, simple CLI free from "the index", revsets, powerful history-rewriting), and Pijul/Darcs (first-class conflicts), with features not found in most of them (working-copy-as-a-commit, undo functionality, automatic rebase, safe replication via rsync, Dropbox, or distributed file system).
[1] https://github.com/martinvonz/jj