
Learn Git Branching - redDragon
http://pcottle.github.com/learnGitBranching/
======
xxbondsxx
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!

~~~
gala8y
_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._

Simply enough, <http://pineapple.io/> was disscussed in another thread [0] few
hours ago and your link happens to be second on the list at
<http://pineapple.io/?reset=true>

Now, hurry up. :)

[0] <http://news.ycombinator.com/item?id=5229185>

~~~
redDragon
OP here. I am so sorry! I saw the link in a reddit post and cross-posted it to
HN. I use Google Reader for reddit RSS and found the site awesome enough to
warrant a HN post.

------
archgoon
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-...](http://git-scm.com/book/en/Git-Internals-Git-
Objects#Commit-Objects)

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

~~~
xxbondsxx
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...](https://github.com/pcottle/learnGitBranching/commit/168852b293697442ea458a96a9c17c15e87a5594)

~~~
Cogito
This is still not quite correct. Let me outline the structure, and then I will
try and submit a PR addressing it.

The first step to committing is staging what should be included.

The staging process specifies an _index_ of files that are to be added to the
next commit. When the commit is recorded, git checks every file/chunk in the
index; a hash is calculated per each of these _blobs_ , each blob and hash are
stored in a key<->object store, the _object store_ , and the hashes are
written into the index of the commit.

If a blob already exists in the store then it is not added again.

When changes are made and committed after this point, the resulting blobs are
then hashed and stored again. Any unchanged blob does not need to be stored
again; any changed blobs are stored.

When a commit is recreated, it's index is evaluated. Each blob is retrieved
from the object store and placed into the tree in the appropriate location.

The most important thing to take out of this? Rebuilding a tree from blobs is
_fast_. Second thing to take out? Git only stores each _version_ of a blob (be
it a file or a chunk) once, so most 'unpacked' repositories are still quite
small.

Now, this is obviously not the smallest representation of the repository, so
git has a _packed_ format which calculates deltas between blob files. This
will calculate blob-deltas even if they are completely separated in the
history; deltas are not between commits, instead they are between objects.
Unpacking deltas recreates the blob objects required to build the tree.

The packing process happens every now and then, but it is definitely not done
every time a commit is made (by default). The most visible place it is used is
when transferring over network protocols (I can't recall if it is done for
_every_ network transfer, but I suspect it is). It is done when running
garbage collection as well.

\----

The reason why all this is important is as I laid out before: rebuilding trees
is fast, which makes fast branching possible, and the object store allows this
without exploding the size of the repository.

~~~
xxbondsxx
I'll be honest -- that was hard to understand. I don't know the low-level
plumbing of git very well, which is why I made a higher level tool like this.

Do you think it's important for beginners to understand all these subtleties?
I think I could maybe eventually introduce them, but for the first level on
the first screen, I don't think throwing a bunch of concepts at them will help
with learning. Feel free to re-open the task if you disagree

~~~
Cogito
I'll admit that I don't know what your knowledge is, so my explanation might
have been directed at the wrong level. I am drafting a pull request that
rewrites this for you, hopefully that will be easier to understand!

I don't think that you need to understand all the plumbing, however it _is_
important to understand how the index works, and that git stores the entire
snapshot. The way it currently appears makes it seem like every time you
switch branches git has to figure out the end state based on deltas, which is
not true. Git has fast branch switching precisely because it stores the
snapshot in its entirety.

[EDIT] Here is what I wrote if anyone is interested: <http://gist.io/4969804>

~~~
xnxn
Thanks for explaining this. Now I understand what the

    
    
        index 1ef56e5..2c756d0
    

in a diff refers to. I'm now poking around in the object store with `git cat-
file -p <hash>` and it's very enlightening.

------
jedberg
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. :)

~~~
wldlyinaccurate
I didn't even realise you could type "help". There definitely needs to be some
sort of introduction prompt otherwise people (like me) are just gonna leave
feeling like they've learned nothing.

Still, nice idea.

~~~
bpatrianakos
Agreed. I'm like you and I was just committing, branching, and merging but
learning nothing while clicking around. I'm glad I know now though because I
can totally use a lesson on branching. I think branching in Git is one of the
most misunderstood parts of Git. I can't tell you how many times I've almost
screwed up a repo because I made some mistake merging branches and not pulling
from the correct branch when working on a different machine. To make matters
worse, if you use Git to deploy into production, testing, and staging
environments like I do you run the risk of pushing development or untested
code into production by accident. I know I've definitely pushed code meant
only for one branch (or feature) into production without merging with
master... it gets confusing but needless to say it didn't take long before
things stopped working and I realized my mistake.

Branching is huge, awesome, powerful, but I know I as well as a lot of
developers I know could use a good lesson on it.

~~~
alinajaf
The implementation of branching in git is so fantastically simple (its
literally a commit hash in a file, `cat .git/refs/heads/master` if you don't
believe me) that it boggles the mind that so many developers have so much
issue with it.

~~~
bpatrianakos
The implementation may be simple but I think what gets people is building a
mental model of all your different remotes and branches. If you're working on
a single machine this is simple. Add in another remote and it's still simple
but adds complexity. Add in 3 remotes, 3 development machiness, and oh say 3
branches and the mental model is hard to juggle. I develop on 3 different
machines and even after about 6 months of this setup which is very close to
the example I gave I still mess things up because I don't think to check what
branch I'm on when I switch machines and pull from the wrong one and other
little mistakes like that.

Branching really is a very simple thing to understand but what I think gets
people in the end is building a mental model of one's own setup and creating
good habits like always running `git status` when sitting down at a new
machine to be sure you're on the branch you think you are, always pushing to
your main remote before switching machines, and making sure to push to the
correct branch in that remote, and so on.

------
ecoffey
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

~~~
xxbondsxx
Discussion here, I'm updating as we speak:

<https://github.com/pcottle/learnGitBranching/issues/6>

------
mappum
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
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
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.

~~~
Flimm
Please improve the error message to at least tell me what window sizes and
zoom levels _are_ supported.

~~~
xxbondsxx
I'm removing this for now, my apologies! This is what happens when a WIP gets
submitted

------
arasmussen
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
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
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
_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.

~~~
cocoflunchy
Thanks, that makes sense.

------
wildmXranat
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
Seems only Chrome exists as a browser. All others need not apply.

~~~
xxbondsxx
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)

~~~
rexreed
It doesn't really layout well in my version of Firefox (18.0.2) - see the
output here: <http://imm.io/WxqQ> and here: <http://imm.io/Wxr8>

You can't see what's happening and the box seems to be improperly sized and
spaced as well as problems with the terminal-style text editing window. The
text flows off the bottom and cursor is misaligned: <http://imm.io/WxrS>

~~~
pbhjpbhj
Same, here FF 18.0 on Ubuntu. Unusable.

------
alinajaf
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
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!

~~~
msoad
Git is amazing, I just wish if there was a better conflict resolving approach
in Git.

~~~
alinajaf
Do you really? I like the fact that git doesn't try anything clever when it
hits a conflict and asks you to fix by hand. Have you found an automatic
conflict resolution tool that you liked before?

------
dljsjr
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
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...

~~~
dljsjr
Your use of live visualizations of the state of the repository is probably the
single best part of the app.

Seriously, very very well done.

~~~
xxbondsxx
Thanks! Really appreciate the feedback, I worked really hard on the animations
and there were a ton of corner cases to solve in order for them to work. But I
do think they serve a huge educational value, so I'm glad to hear the work
(and code) paid off.

------
leetrout
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
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!

------
mawuli
Great work. I recently found a very practical use of Git. I call it the "Poor
man's hot code loading". This is a post i just wrote on it
[http://blog.mawuli.me/2013/02/poor-mans-hot-code-loading-
git...](http://blog.mawuli.me/2013/02/poor-mans-hot-code-loading-git-
branch.html)

~~~
homosaur
I like this, I use Git in this way on my testing server quite often.

------
shurcooL
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
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
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

~~~
jspiros
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.

~~~
xxbondsxx
Yep! Exactly. The status of the current branch your on is designated by the
asterisk (like in real git), but in retrospect I guess it could be a bit more
clear...

------
newtang
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
This is a _fantastic_ idea! Just like chess puzzles, only for git. Would be a
_great_ deliberate practice tool.

~~~
newtang
Exactly, the chess puzzles are a perfect comparison.

------
swah
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
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.

~~~
xxbondsxx
I also spoke to the Github guys about integrating this into their set of
training tools (try.github and a few docs), but I think they got caught up
with their full time responsibilities because I haven't heard back in a while.

I could commercialize it but it deserves to be free!

~~~
orangethirty
You do know that with the license you currently have in there anyone can just
sell it, right? You don't have an issue with that?

~~~
xxbondsxx
I'd be really disappointed if someone added one level and started selling a
zip file of the application to enterprises for $400 a pop.

That being said, I've heard the GNU license is sometimes too prohibitive
(albeit no definitive examples). If you know licenses at all, I'd love some
advice

~~~
orangethirty
$400? This would sell for _thousands_ in the right market. Add in training,
and you have a long time gig here. This would even be a great online training
business. So many possibilities.

Right now, you cant be disappointed if the license allows it. If you have
doubts, change it _now_. In terms of licenses, I'm not really an expert. But
you could just roll your own. Just take the one you have right now, and remove
what allows people to sell it. Still won't stop some people from doing it,
though.

For example, I forked your repo. Why? Because its such a nice platform, that I
want to learn how it works. I saw that about other 20 people had forked it
too. What is stopping them from putting up a website and selling it? Nothing.
Nothing at all.

Open source is awesome and all. But you have to also be aware that there are a
lot of ruthless people out there waiting for programmers like you to put out
software like this one under such licensing terms. Its like buying a car, and
listing everyone you know as an owner in the title. Can't get mad when they
sell it.

------
2mur
Awesome. Using some lovely client side tech: backbone, browserify. Going to
have to really spend some time looking through the code. Cheers!

------
devin
This is great. Adding this to my list of resources for beginners. The ability
to build levels, export trees, etc. makes it even better.

------
aymeric
Would be nice to see the solution of a level, to compare it with what we have
done (and to find the solution if we are stuck).

~~~
xxbondsxx
You can type in "show solution" to see the solution for a level (after a
prompt). I'll have to add this to some help dialog somewhere...

(again I apologize about the discoverability for different commands -- was
going to document all this before submitting)

~~~
aymeric
Thanks!

------
joeblau
This looks awesome! Thanks for putting this together. It's hard to keep
something cool under wraps :)

------
Flimm
C1' has two meanings, one is the result of a rebase, and one is the result of
a revert. I stared at level 2 of "master the rebase, Luke" for a while before
I realised this. I think these two things should be have different notations
(maybe C1' and C1^-1, or C1' and C1r).

~~~
Flimm
In fact, I solved that level using only 'git revert' commands, which I don't
think was the intended solution. And the displayed solution isn't complete: it
asks the user to perform an interactive rebase. (I'm not complaining, just
feedback.)

~~~
xxbondsxx
That's a good point. I should just disable revert in all levels except for
those related to it. I rarely revert in practice so it's not a huge issue.

Showing the concept of a "modified" commit is hard though. That's why I did
all the C1' sillyness (like the man pages do). The apostrophes also scale
nicely (up to C1'^99) where reverting a reverted rebased commit might make the
text too big.

EDIT: Fixed, see: <https://github.com/pcottle/learnGitBranching/issues/7>

------
r4pha
shameless plug: www.srctree.net - Ace editor + git + canvas for viewing
commits/branches.

I built it about a year ago, mostly for learning and fun. I haven't advertised
it a lot but it seems relevant in here. I hope it's not off topic!

~~~
contingencies
Interesting but how to get other code in there is not so clear. Could be
useful as an educational tool, with nicer defaults.

~~~
r4pha
I'm not sure I get it. You can start coding and just keeping on commiting and
it will handle branching automatically. No doubts that I should make that
clear somewhere.

------
edgarvaldes
I don't get how it works.

~~~
deweerdt
You can:

\- 'git checkout -b branch_name' to create a branch

\- 'git checkout branch_name' to switch branches

\- 'git commit' to add dummy commits (no need to git add stuff)

Edit: formatting

~~~
famulus
You can also:

-'git rebase branch_name'

-'git merge branch_name'

-'git checkout C6' to enter a detached head state

------
sleepybrett
I worked my way up to branch spaghetti, where I went into the deep end, the
solution for it uses commands and concepts not well introduced in the
proceeding 'puzzles' (rebase -i)

------
dsjoerg
very nice idea. when/if this supports git push i'll come back and play some
more. i'm a total git noob, git makes me crazy and maybe this will help
clarify things for me.

~~~
d0m
I suggest you take the time to learn the "core" before memorizing all the
commands.. everything will be so much easier : )

------
Tomino
Awesome work, obviously author has spent a lot of time on this and thought it
through. Even with advanced GIT skills, it made me think about few things.

------
fiatpandas
Buggy in Firefox. Stoplight window buttons not correctly placed, and the
popups aren't centered-- they just align to the upper left

------
g3orge
you need to replay the solutions slower...

------
js-coder
Dude, this is epic! Really great work.

------
miga
Please support git fast-forward!

------
joebeetee
Beautiful. Great job.

------
happypeter
Have tried merging and rebasing, absolutely wonderful!

------
alexzhan
The back array does not function well.

------
ExpiredLink
I don't see how this could be helpful. Does the author imply that there exists
only one branching and merging strategy for any CVS?

~~~
Cthulhu_
No? Else the link / project would be called "Learn CVS Branching"

------
justplay
Great work. Thanks for releasing .

------
memming
type 'level' to start.

~~~
cpayne
Wow! How did you find that?

~~~
kaichanvong
I typed help first.

------
seivan
Great job. Would be cool if you told people about git flow once you notice the
pattern further in.

