The Git Internals section of the Pro Git book covers commits [1] and branches [2] well though it doesn’t go into details about merges and rebases.
[1]: https://git-scm.com/book/en/v2/Git-Internals-Git-Objects
[2]: https://git-scm.com/book/en/v2/Git-Internals-Git-References
Branching is more of an art. With the kind of flexibility git provides, one can get lost in the convention to follow. I have found this useful For a small team working on app development -
Ungit[0] shows what will happen to the tree before you execute a merge or rebase. It really helped me get a hang of Git.
I wrote my self a note about this last year to demystify the internal data structure [0], if you want to check it out. But the TLDR straight to rabbit holes; is that commits are a directed acyclic graph (DAG) [1]. And the file tree snapshot is a fully persistent trie [2]. And the commit DAG points to different snapshots. Branches are name shortcuts to commits.
[0] https://sransara.com/notes/2019/build-yourself-a-git/ [1] https://en.wikipedia.org/wiki/Directed_acyclic_graph [2] https://en.wikipedia.org/wiki/Persistent_data_structure
Does anyone have a really good visual explanation of what's being done to the tree and such when commits and merges and rebases are done? I still don't quite grok it intimately enough.