Yes, that's the underlying execution model. The approach of the article "git from the bottom up" is that one needs to understand this in order to use it, rather than being able to understand it in terms of the UI.
Taking a lateral step towards the ease-of-adoption and learning of a tool, there's an intriguing aspect of git that I want to articulate further:

To understand part of git, you must first understand all of it.

Several aspects of git are interconnected; some design decisions don't make sense in isolation; and you need to know the detailed and apparently incidental behaviour of some commands in order to be able to use them. It's an expert tool.

As an ideal (perhaps unrealizable), a tool has a learning curve, with a series of "closed" subsets of functionality, such that each subset is complete in itself. Learn a subset, and you are a master of that aspect. (I'm using "closed" not in the strict mathematical sense of the results of operations being in the domain of their operands, but to mean that you don't need to go outside that subset). It's a similar concept to minimizing coupling between modules.

e.g. you can play UT without knowing about alternate fire; you can using basic reg exps without knowing all the weird clever stuff; you can write C in C++. Languages especially have this quality - you can write procedural code in an OO language, you can use one library without using all the libraries.

Git doesn't do this.

As an example, if you want to change the message of a commit, you need to create a new commit with the new message. This immutability is important (I infer) so that other instances of the repository can remain in sync (the new commit will have a different hash from the old one (with a very high probability), because the message is different). Thus, the apparently simple operation of "changing a message" is interconnected with the distributed nature of the tool.

If you want to change the message of the first commit (at the root of the DAG), it is more complex. First you 'change' the message of that first commit, via making a copy (as above) - but the rest of the DAG is still pointing to the old root, not your new one. Therefore, you rebase (disconnect and reattach a node) the child from the old root to the new root. Finally, rebase does not actually disconnect and reattach - it makes copies (immutability again). You haven't changed the old DAG, but created a new one.

Changing a message is not as simple as one might expect.

An additional problem is that the documentation (man pages) doesn't always define terms, and not always clearly. But they are obvious to someone who already knows how it works (and doesn't need the man pages, except for reference). BTW: I found that some terms are defined at the end of the options section (the definitions aren't always complete or unambiguous, but they help); and it's helpful to think of the type of the arguments (though the man pages don't use that term)

Please don't take this as a disparagement of git - it is an expert tool, tackling and solving some extremely difficult problems of a master. I understand it took Linus years of coping with the problem, and of having the brilliant example of bitkeeper before he could whip up git overnight. I've invested quite a bit of time to reach the (limited) understanding that I have so far, and each step teaches me more about the problems and solutions of serious distributed version control. It is complicated because the problem is complicated; and it remains complicated because a master already grasps the problem, and can cope with that complexity.