Some developers find Git takes a little getting used to, claiming that it is conceptually convoluted compared to other distributed version control systems. I used to number myself amongst them.
Happily, I’ve found that a couple of simple spatial analogies have made me proficient and fluent in using Git’s command-line interface.
One of the things that tripped me up as a novice user was the way Git handles branches. Unlike more primitive version control systems, git repositories are not linear, they already support branching, and are thus best visualised as trees in their own right. Branches thus become trees of trees. To visualise this, it’s simplest to think of the state of your repository as a point in a high-dimensional ‘code-space’, in which branches are represented as n-dimensional membranes, mapping the spatial loci of successive commits onto the projected manifold of each cloned repository.
The authors of the git manuals clearly had this in mind. Taken directly from the git manual:
In simplified form, git object storage is “just” a DAG of objects, with a handful of different types of entries from <commit> to the index, optionally modifying index and working tree to match. The <commit> defaults to HEAD in all forms.
If <branch> is specified, git rebase will perform an automatic git checkout <branch> before doing anything else. Otherwise it remains on the current branch. All changes made by commits in the current branch but that are not in <upstream> are saved to a temporary area. This is the same set of commits that would be shown by git log <upstream>..HEAD (or git log HEAD, if –root is specified). The current branch is reset to <upstream>, or <newbase> if the –onto option was supplied. This has the exact same effect as git reset --hard <upstream> (or <newbase>). ORIG_HEAD is set to point at the tip of the commits that were previously saved into the temporary area, then reapplied to the current branch, one by one, in order. Note that any commits in HEAD which introduce the same textual changes as a commit in HEAD..<upstream> are omitted (i.e., a patch already accepted upstream with a different commit message or timestamp will be skipped).
Update: There is, of course, a fabulously insightful commentary on reddit.
Update: Thanks folks. You’ve made my usual one or two hundred daily visitors look kinda paltry: