This has been posted before, but I thought it was especially good, and the opportunity for comments on the older version (from over 600 days ago) are gone.
If you want to read the previous discussion it's here:
Thanks for reposting - I hadn't caught it the first time through and thought it was a good read.
Started off easy enough (loved the simplification), but as soon as we got to SHA-1 snapshot names and "Rewriting History" with the redoing of snapshots and then to the staging directory my eyes glazed over.
It dawns on me that:
1. I have been using every SCM since CVS basically like CVS (Subversion and Git specifically).
2. I have a GitHub account I use to host all my open source and commercial code.
3. I got it because it was the "cool thing to do" and I felt left out of the loop ignoring Git for so long.
4. I have no idea how to really use Git in the ways that make Git a powerful thing.
5. The few times I have seen real Git errors like "Snapshot cannot be rebased, please schnoggleford your glerpentrap!", they have freaked me out and never been immediately obvious as to what is wrong; if it weren't for Google search'ing error phrases I would probably be using post-it notes with hand-written source code as my SCM system.
6. I REALLY want an graphic showing these different concepts explained in the article. I am a visual learner and reading (at 6am) through the snapshot re-parenting section without visual indicators of what is actually happening just isn't clicking.
It seems to me a graphic compliment to this article of what situation the main character has every step of the story would make this pretty much the ultimate "get your bearings" resource for new Git users.
At least I think so.
Who knows, I'm still excited when my pull and push commands complete without errors :)
I'm also a visual learner, I found reading http://eagain.net/articles/git-for-computer-scientists/ really helped me gain a deep understanding of how git repositories work. It goes into quite a bit of detail but I found that once I'd groked it the various git commands made a lot of sense and that I could really use them in my workflow.
I used to be in your situation. It isn't worth using git if you don't have time to learn the really powerful things you can do with it. git can increase your productivity by leaps and bounds - but you have to learn more than the basics.
I only ever explain git to people with the aid of a whiteboard for exactly this reason. Drawing the DAG makes it much more clear, and it's what I see in my head when I type commands now...
Same here - having the DAG up and being able to change where things point easily is awesome. If I were pressed to explain git without being in person, I rather liked the Git Parable.
i'd love if you were to film it next time, I get git, and i can handle git, but i'd like to really deeply understand it- and visual reference may help :)
I can't draw, but IMO git's basic operations are pretty easy to visualise if you think of the repository and commits as a graph (a tree). You start with the first commit/snapshot as the root, and every node after that is a child of the root. To bring diffs into this model, I suppose you could think of the edges as the "diff" between two snapshots; ie. how to get from node A to child A'.
The staging area is pretty simple. You can think of it as a "WIP" snapshot: it's what gets recorded in the tree when you make your next commit. It may seem like extra work if you're just used to committing every change you have in the working directory, but at least I tend to not want to do that, and git has some pretty cool tools for crafting neat commits out of working tree contents. :)
A node can of course have multiple children, so branches are natural in the git world. "Named" branches are merely pointers to a snapshot somewhere in the branching structure of the tree.
Merges happen when two branches join together: a new merge snapshot M has edges from both parents A and B (or more, if needed) representing the conflict resolution, and M represents the finished merge.
Rebasing or reparenting is somewhat different. You can think of it as cutting a branch from the tree and gluing it elsewhere. ie. if you rebase branch B onto branch A, then the divergence point of A and B is looked up, and all the edges (diffs) from that point on until the tip of B are applied on top of A, resulting in a series of completely new snapshots. This is why rebasing is "dangerous" or destructive: branch B is no longer the branch it once was, but something completely different.
Unlike in a merge, information about the original branches, or any changes needed to fit the changes on top of the new base, is discarded.
Of course, git won't actually destroy anything during rebases either. As long as you keep a reference to the original branch B, git will keep the snapshots and you can go back to them. There's just no straightforward way to tell that the original B has at one point been rebased on top of A.
EDIT:
I think I should note that every "ref" in git is a reference to this giant tree data structure. Let's take for example origin/master. When you fetch changes from the origin repository, git fetches snapshots from the remote data structure, includes them in your own local one, and updates origin/master reference to point to the correct tip in the data structure so that it corresponds to the remote's master branch.
The same happens for other branches, too of course, depending on what you tell git to fetch. (git can also handle snapshots completely unrelated to other commits in the repository. ie. you can have multiple root commits, but that's not often done. :P)
A "pull" then goes a step further and merges your local 'master' with origin/master and updates your local reference. (origin/master remains untouched until you fetch new changes or successfully push your merged master to the remote)
In essence, git manipulates references to a growing, mostly immutable, distributed data structure. I think it's simple and elegant, but YMMV. :)
If you want to read the previous discussion it's here:
http://news.ycombinator.com/item?id=615308