I'm a huge fan of git (but became one the hard way) and I think that most of the poor design decisions are in the command layer. Largely the tendency for the same command to do several things that, to the user, are wildly different (often because they map to the same fundamental operation on the DAG).
As the most simple example, git add both adds a new file to the index and adds changes to an existing file to the index. They are both fundamentally the same operation, but your intentions are different.
Checkout, likewise, both changes HEAD's symbolic reference and changes the working copy to match the index or a commit. This makes it both a means of full tree changes and local reversion.
And then there's rebase...
I don't think these are huge issues, but I do think they're barriers and a source of common early issues with git for new users.
This is exactly what I was getting at. git's command layer is much like the "new" keyword in Javascript -- it's a false abstraction of a relatively elegant underlying system [1]. As it is, the command layer encourages a naive mental model that is both inaccurate and leaky. You end up having to learn both the abstraction layer and the actual system underneath in order to actually understand what any of the commands do.
[1] I assume this was originally done to make git seem more approachable to SVN or CVS users.
I find that SVN users have the most trouble with git, so I don't think that's true. Mercurial has a similar underlying model but has a porcelain layer that svn users find far more comfortable.
The branch switching behaviour definitely seems taken from cvs, but somehow works much much better than it ever did in cvs.
I assume you're referring to the use of the different flags?
For the latter two, no disagreement there. For the former two, there is a difference between returning a verbose response within the context queried and expanding the inclusive parameters of the query. 'git remote -a' makes no sense as all remotes are equivalent (there is no such thing as a local remote).
If you're curious, "git remote", "git branch", and "git tag" all present a list without supplying those options. You only need "git branch -a" if you want to see remote branches.
"git stash" is certainly the outlier; the reason is that when "git stash" was first added it was meant to be a short-and-sweet command. Otherwise, you'd be forced to type "git stash save <name>", which is not so short and sweet. "git stash list" was added later.
I agree the CLI can be a pain, but it's slowly improving. It's in a better state now than it was a few years ago. For example
git push origin :topic-branch
can now be replaced with
git push origin --delete topic-branch
This still has issues, there's now multiple ways to do the same thing. There's also different commands (git push vs git branch) for the same action, deleting a branch (regardless if it is remote or local).
Not sure what ender7 refers to. As far as I know, there are a few things in git that its maintainers think are missing - e.g.,
Linus mentioned that having a "generation" in a commit, which is 0 for the empty commit and 1+max(generation of ancestors), would have sped up some merge operations.
Finding the history of a single file requires traversing the entire commit tree.
But there is no "fundamental" problem or bad design choice - and in fact, this data can easily be cached without adding it into the protocol.
EDIT: saw some complaints listed in this thread - they all have to do with UI, not with a design choice that is limiting use. Wrappers like "eg" and "legit", and macros, can be used to fix the UI (except no one agrees on what a better UI looks like).
"saw some complaints listed in this thread - they all have to do with UI, not with a design choice that is limiting use."
For many people, UI issues carry way more weight as "design choices that limit use" than issues such as speed, efficient disk usage, data normalization, etc.
"Wrappers like "eg" and "legit", and macros, can be used to fix the UI"
I disagree. There may be some that _could_ be used, if 'the internet' wasn't filled with helpful comments using the 'real' UI. As it stands now, there is no replacement that has sufficient market share to give users a good chance of finding questions to answers they may have. It is a bit like the early days of Windows, where "how do I..." Questions got answered by "that's easy. Exit to DOS..." (Linux on the desktop has a bit of a similar problem, but I think it is slowly outgrowing it)
"except no one agrees on what a better UI looks like".
That may be an indication that it really is hard (maybe even impossible) to find a good alternative UI hat does not leave out git features.
The commands, my god there are numerous commands that have no rhyme or reason.
Want to checkout a branch?
git checkout <name>
Want to make a branch?
git checkout -b <name>
Want to reset a file?
git checkout -- <file_name>
Want to make a sandwich?
git checkout ++D@A#32
Want to rebuild universe from Big Bang?
git checkout 0 --rebuild-universe
Add to this, duplicated commands, arcane commands (hello fsck --lost-found), commands that seem deceptively similar but aren't, doesn't work out of the box like hg, doesn't work on Windows etc.
I love git, but its CLI is horribad. And that is after most of weird/confusing stuff was removed...
Git, like Linux is a power tool. It's like those drills that can drill through solid rock easy, but if they jam, they'll spin you around.