Staging area and stash are simple too. Here I'll explain it in 10 seconds:
* The staging area/"index" is a draft commit. You can add or remove things to the draft. When you run `git commit` it turns the draft into a real commit and the draft becomes empty again.
* Stashes are just "WIP" commits. They don't have a branch name pointing to them but you can list them all. When you apply or pop (apply & delete) a stash it takes the diff from the stash commit (versus its parent) and applies it to your working tree.
Submodules conceptually are relatively simple but the actual implementation is stupidly buggy and confusing. Like, I still have no idea what "submodule init" does. Why are there two places where submodules are stored - `.gitmodules` and a second secret place that you can't see? Why isn't `--recursive` the default? Why doesn't switching branch also switch the submodules?
Most of the answers to that are "well it could work properly and be simple, but actually it's half-arsed and full of bugs". You can seriously break your repo with `git switch --recursive` or if you try to use work trees with submodules.
Yes but none of those things sound like they needed to be first-class built-in parts of git and instead could've been just plug-in tools built on top of git. Like stashes could just be a set of branches named stashes/<stash name>, with external scripts handling the stash/pop mechanic.
And given the choices in things that get first class support in git, "which branch was this commit originally made in" or "no you don't need to care about that intermediate commit" or "what commits were derived from this commit" or "what branch is this commit in" seems like they would've been more useful problems for the freeping creaturitis to solve.
* The staging area/"index" is a draft commit. You can add or remove things to the draft. When you run `git commit` it turns the draft into a real commit and the draft becomes empty again.
* Stashes are just "WIP" commits. They don't have a branch name pointing to them but you can list them all. When you apply or pop (apply & delete) a stash it takes the diff from the stash commit (versus its parent) and applies it to your working tree.
Submodules conceptually are relatively simple but the actual implementation is stupidly buggy and confusing. Like, I still have no idea what "submodule init" does. Why are there two places where submodules are stored - `.gitmodules` and a second secret place that you can't see? Why isn't `--recursive` the default? Why doesn't switching branch also switch the submodules?
Most of the answers to that are "well it could work properly and be simple, but actually it's half-arsed and full of bugs". You can seriously break your repo with `git switch --recursive` or if you try to use work trees with submodules.