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.
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.