One data structure under all the commands
Git has a reputation for an inconsistent command line, and it is deserved. The data model underneath is small, regular, and worth learning first, because every confusing command becomes obvious once you know what it manipulates.
Git is a content-addressed key-value store. You hand it content, it returns a hash; you hand it the hash, it returns the content. The key is computed from the value, so it is not chosen and cannot be changed independently.
Everything is built from four object types stored that way, and there are no others. Not a diff, not a changeset, not a patch: those are computed on demand for display, and the storage is whole snapshots.
That is the first surprise for people arriving from other version control systems. Git does not store what changed. It stores what everything was, at each commit, and derives the differences when asked.
The rest of the model follows from that choice, including the properties that make branching cheap.

