top | item 5232415

Learn Git Branching

717 points| redDragon | 13 years ago |pcottle.github.com | reply

137 comments

order
[+] xxbondsxx|13 years ago|reply
Wow! Author here, did not expect this to get submitted to HN yet (was going to finish out a few more levels this weekend and clean everything up). Forgive the giant "TODO" in the help dialog

The link everyone should see is the demo: http://pcottle.github.com/learnGitBranching/?demo

That shows a few example commands, the completion of a level, and finishes with the help dialog.

Some interesting technical highlights

- I made heavy use of javascript "Promises" to route control through the entire app. The source code has some nice examples, but it would be callback spaghetti without it

- You can import and export trees to share with your friends ("import tree" and "export tree" commands)

- You can build levels from within the app with "build level". The intro diaog should step you through the process

- It even supports interactive rebasing! Try it out with "git rebase -i HEAD~3"

Git is a fairly complex too that can be explained really well graphically. I never understood what I was doing until I saw diagrams in the git manpages and various books around on the internet. I wanted there to be an interactive form of these diagrams but it didn't exist --- so I built it.

9,000 lines of JS later I have this. There's still some polishing to be done, but I'd love for the community to share their knowledge about different git workflows and different ways to explain git concepts.

I tried to make the bar for contributing as low as possible. You can build a level and submit a pull request without even cloning the repo!

[+] nwhitehead|13 years ago|reply
Very nice! I worked through all the levels you have and everything worked great, it was a lot of fun.

Some notes: I "cheated" and used cherry-pick before it was introduced, not sure if that should or should not be allowed. Sometimes I was frustrated because my graph looked like the goal except for "ghosted" nodes, had to go back and figure out a different way to solve the level the right way. I wished I had an "undo" feature to take back moves rather than resetting everything. Lots more hints would be good, this stuff is hard.

Honestly I learned more git in the last 10 minutes than I've learned in a year of using git, or from several hours reading git tutorials.

[+] malandrew|13 years ago|reply
Absolutely brilliant work. I would love to see this expand out into a key reference for git beyond just learning branching. One great feature would be to support "learning modules" where anyone making a git tutorial could define their own lesson modules. This would go a long way to help people learn all the cool features of git, which is very daunting.
[+] ndonnellan|13 years ago|reply
So cool! I'm new to git (coming from mercurial) and think this would be awesome as a general purpose tutorial.

Unfortunately it seems to assume some knowledge. For example, rebase is introduced in a very understandable way, but then I need to know what "rebase -i HEAD~4" does without being introduced to those concepts.

[+] eranation|13 years ago|reply
Hi Looks great, looking at the code, I'm trying to wrap my head around how you do your resource loading, the require call doesn't seem like RequireJS, and I found that the require method is defined in the bundle.js file. Are you using http://bundlejs.com?
[+] jasonm23|13 years ago|reply
Fantastic work, I'd suggest that you provide walkthrough on each the solution, so that it's easy for people very new to git to follow along.
[+] littledot5566|13 years ago|reply
Thanks for all the hard work! As a git noob, this is extremely useful to me. Thanks again!

By the way, what are some recommended git GUIs for linux?

[+] Mahn|13 years ago|reply
This is pretty epic, thanks for making it.
[+] agsamek|13 years ago|reply
I got stuck on Level 2 - created a few more branches and I couldn't complete the level. Goal completion check should be more open for additional work done as long as the main goal is completed.

Alternatively - some way of level reset should be provided.

Anyway - this is great work!

[+] plumeria|13 years ago|reply
Thanks a lot for this!!! Keep up the good work!
[+] benihana|13 years ago|reply
What's the point of having a close button on a dialog window that doesn't close the dialog?
[+] archgoon|13 years ago|reply
This tutorial is great, but it propagates a misconception about git.

"A commit in git is a recorded set of changes that you have made"

Git commits are _not_ deltas. They are entire snapshots of the repository and a single (optional) pointer to an ancestor commit[1]. Git may handle _compression_ in terms of deltas (see 'Packfiles' in [2]), but logically, a commit should be thought of as equivalent to the state of all files that are being tracked. That difference is that if you were only looking at diffs, commits would be the _edges_ of a graph, rather than a node plus a single edge. This is why rebases change the commit SHAs but not merges (and why merges create a new commit). This is why if you are on a merge branch, 'git checkout HEAD~3' may not bring you to where 'git log' would naively suggest.

Version control systems that actually do think of 'commits' as pure 'deltas' are ones such as darcs.

A really good, low level explanation, of git is here

http://git-scm.com/book/en/Git-Internals-Git-Objects

(BUG REPORT) The commit created with 'git merge b2' from branch b1 should have HEAD~1 point to the previous head of b1, not b2.

(that said, this is a really cool thing. :) I look forward to the author adding support for conflict resolution. )

[1] http://git-scm.com/book/en/Git-Internals-Git-Objects#Commit-...

[2] http://git-scm.com/book/en/Git-Internals-Packfiles

[+] xxbondsxx|13 years ago|reply
Thanks a ton for catching this. I guess there is a distinction to be made -- the compression might use delta's, but a commit specifies the entire state of the repository.

It's a tricky line to walk though, because commands like "git show" and "git patch" clearly show the delta-like nature of a single commit. I also don't want newcomers to think that commits are heavy and should be used sparingly.

I'm totally down to discuss this on a github issue with you, we could go over the wording. Maybe something like "a commit specifies the entire state of a repository, but is usually stored on disk as a set of changes"?

EDIT: moving discussion to: https://github.com/pcottle/learnGitBranching/issues/6

EDIT: fixed in: https://github.com/pcottle/learnGitBranching/commit/168852b2...

[+] js2|13 years ago|reply
They are entire snapshots of the repository and a single (optional) pointer to an ancestor commit

Nit: A commit can have multiple ancestors, as in a merge.

[+] jedberg|13 years ago|reply
It would be great if the help page popped up when I first load the site, so I don't have to guess and type "help" at the prompt to find out the purpose of the site. :)
[+] ecoffey|13 years ago|reply
This is really really great. Good visualizations of how git works are really awesome and useful, so thanks!

That said, the intro lesson introduces commits as exclusively deltas. This isn't accurate, and would probably cause confusion with later concepts.

Commits are really snapshots of a tree object (with probably a whole lot of sub trees, and a whole lot of blobs). Since part of the commit meta-data is the parent sha, it's really easy for git to show you the delta, but at it's core git cares about linked snapshots of trees.

I am now done being anal retentive :-) thanks again for the great site, excited to see it more fleshed out

[+] mappum|13 years ago|reply
My only criticism is that there a million modals you have to go through, and some are even multi page, adding complexity. I would rather have fewer modals/pages that show more text at once.

But overall, this is super handy, great idea :)

[+] jlgreco|13 years ago|reply
I would try it out but, fullscreened, I get the message "That window size is not supported :-/"

How about letting me worry about that and continue anyway? What is the worst that could happen, I have to use a scrollbar?

[+] xxbondsxx|13 years ago|reply
I support a fairly wide range of zoom levels... from +3 levels zoomed in to almost any level zoomed out. The main reason why I can't do more than 4 is the way canvas pixels interact with screen pixels and some of the text positioning logic.

If you're at a normal zoom level and getting that message, certainly let me know -- the zoom level detection logic is a unfortunately pretty hacky.

[+] arasmussen|13 years ago|reply
I found it a bit annoying that the "Alert!" dialogs in the beginning looked like a window but didn't work like one whatsoever (couldn't minimize, close, maximize, or move around). Probably shouldn't make something look like a well-known UI if it doesn't behave like that UI, especially to the point where familiar buttons don't work.
[+] snip596|13 years ago|reply
Awesome visualization, but it seems to deviate from how git works in a few instances. Take "level mixed2" for example. The initial branch checked out was "caption". I did "git rebase -i master" and picked both commits (no re-ordering). That created C2' and C3' which is not correct. C2' wouldn't have been created because it's the same tree as C2 with the same ancestor.

I had other issues with that level as well. It seems to be teaching inefficient habits by forcing strange rebases rather than a single one with an "edit" on C2. I understand this might be a limitation on the (really cool) visualization, but maybe those levels shouldn't be included if you can't show the most intuitive way (at least to me) to accomplish the goal.

Otherwise, awesome work!

[+] cocoflunchy|13 years ago|reply
This is a great tool, thanks so much !

I have trouble understanding the rebase workflow: What is the difference between these two sequences?

    git checkout -b bugFix
    git commit -m "fix"
    git checkout master
    git commit -m "master stuff"
    git rebase bugFix
    git checkout bugFix
    git rebase master
and

    git checkout -b bugFix
    git commit -m "fix"
    git checkout master
    git commit -m "master stuff"
    git checkout bugFix
    git rebase master
    git checkout master
    git rebase bugFix
Is it just the order of the commits in the final tree that will be different? Or I am missing something else?

Instinctively I would tend to do the first one, but that was not what lesson 4 expected...

[+] csense|13 years ago|reply
Rebase works by discarding commits and replacing them with different commits.

If you rebase, then anyone who has the old commits in their repo will have to use git reset --hard to switch to the new branch. In other words, rebase inconveniences all other users of a branch. So you can use it freely on branches that only you work on, but you should be reluctant to use it on branches used by other people -- especially popular branches like "master".

If you use your first workflow, the app clearly shows that you discard the commit C3 ("master stuff") and replace it with a different commit C3'. This requires everyone on master to reset.

If you use your second workflow, the commit that you're discarding is C2 ("fix") instead. This means that only people who checked out C2 on bugFix need to reset.

[+] jedbrown|13 years ago|reply
In both cases, the second 'git rebase' is just a fast-forward (moving the ref ahead without modifying the graph). Thus we need only distinguish what happens in the first 'git rebase', which is a different choice of which patch gets rewritten. Note that you can shorten

  git checkout bugFix
  git rebase master
to

  git rebase master bugFix
[+] wildmXranat|13 years ago|reply
Since the author mentions that it's not ready for submission and use yet, I won't complain that I didn't know what to do with this demo at first.

After reading these comments, it became obvious how great the thing is and going back with that in mind made the app more enjoyable

[+] insteadof|13 years ago|reply
Seems only Chrome exists as a browser. All others need not apply.
[+] xxbondsxx|13 years ago|reply
Should work on Firefox, Chrome, and Safari. Anything specific you are noticing in another browser??

I rely pretty heavily on the box model for layout, but if you look at the CSS I included almost every browser extension (even Opera)

[+] alinajaf|13 years ago|reply
Excellent work! I've wanted an easy way to explain git branching to people and from now on I'll point them to this.
[+] tiziano88|13 years ago|reply
Same! Sometimes I would like to introduce my coworkers to the amazing world of git, but it's hard to convince them without showing them a concrete example, this one is a pretty nice overview, and also useful for advanced users! I just got a better, more intuitive understanding of what detached HEAD really means thanks to it!
[+] dljsjr|13 years ago|reply
Absolutely fantastic tutorial, but as most other people here have mentioned there should probably be some indication that you should type help to get started.
[+] xxbondsxx|13 years ago|reply
I just pushed the site live, so it starts off with a help dialog and links to the demo. Future visitors should hopefully get a better experience!

My apologies again -- I only noticed it was on HN when I got an email about it...

[+] leetrout|13 years ago|reply
I'm only getting started with the tutorials but this looks really promising!

I also like the fact that there are no instructions on the page which would make this really useful as a quiz tool to see how students / interview candidates / etc approach the problem space. I fully intend to fork and try to make my own levels when I get some free time.

Great concept. Is this based on something else similar or entirely new?

[+] xxbondsxx|13 years ago|reply
LearnGitBranching is somewhat the intersection between try.github.com (which has the whole fake command line thing) and the diagrams drawn in the git manpages. Try.github was an awesome way to present a tutorial, but it wasn't the full-fledged demo I wanted it to be. A few months later I came out with this!
[+] shurcooL|13 years ago|reply
Nice stuff. This kind of branching visualisation is highly useful. I'd like to work with that kind of interface. I suppose I should use gitk or something similar?

How did you create the branch visualization? Did you use some sort of library for displaying and animating connected nodes, or is it all coded from scratch?

[+] xxbondsxx|13 years ago|reply
I had to code it all from scratch unfortunately :-/ I looked at d3.js, arbor.js, and a ton of other libraries but none of them supported the tree layout I had in mind. Apparently visual tree layouts are PhD dissertation topics so there's a wide variety out there

I think a lot of educational value is in the animations as well, so it made sense to roll my own. The majority of the code involves all the visual and GUI elements -- re-implementing git (ironically) wasn't too bad!

[+] nodesocket|13 years ago|reply
What is the difference between doing:

     git checkout -b bugFix
     git commit
     git checkout master
     git commit
     git merge bugFix master
And

     git branch bugFix
     git commit
     git checkout master
     git commit
     git merge bugFix master
[+] micampe|13 years ago|reply
git checkout -b bugFix creates the branch and puts you on that branch, git branch bugFix creates the branch and leaves you where you are, so in your first example you are committing on the branch and then merging to master, in the second example you are always committing to master.

try it in the website and you’ll see that in the second case bugFix never changes. the merge will say nothing needs to be done because bugFix already contains all changesets in master.

[+] jspiros|13 years ago|reply
Creating a branch with

  git branch bugFix
does not automatically check it out, so you'd have to follow it up with

  git checkout bugFix
but if you do

  git checkout -b bugFix
it will create the branch and then check it out all in one step.
[+] newtang|13 years ago|reply
This is really well done. Nice job!

Another direction you can go with this is to make a series of Git puzzles. Basically, starting with this diagram A, convert to diagram B in the least number of moves. To be extra useful, these could revolve around common Git pitfalls.

[+] charlieflowers|13 years ago|reply
This is a fantastic idea! Just like chess puzzles, only for git. Would be a great deliberate practice tool.
[+] swah|13 years ago|reply
I thought I knew enough git, but the other day I was still able to lose my changes...

Suppose I'm in master and already modified a file, and now I notice that it would be better to work on a devel branch with those changes, so I could pull upstream changes from master and merge locally. I think I did something like this:

  git stash
  git checkout -b devel
  git stash apply
  git add file.txt
  git commit -m "XYZ new changes" 

  git checkout master
  git fetch
  git rebase origin/master (to avoid an empty merge, changes
                            upstream were in independent files)
  git merge devel (to get commit "XYZ")
In the end of this, I had lost my changes in file.txt.
[+] orangethirty|13 years ago|reply
I would seriously consider packaging this as an enterprise teaching tool for developers. Companies buy this sort of tools for training. Very good commercial potential here.