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
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!
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.
Wow that's great to hear! Seriously, really glad someone found it useful. That's the entire reason I built it.
Levels support a "disable-map" that will prevent certain commands from executing. I somewhat foolishly assume that users only learn commands as I introduce them, but I should go back and lock down some of the levels.
Also, I'm working on a way to compare trees without the ghosted nodes --- it's a bit tricky, but if anyone loves graph traversal and would love to help, chime in on github!
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.
That's a great idea! Right now I'm totally willing to accept levels with the current functionality, but it would be great (like you said) to be able to cover all the aspects of git. Staging / committing, branching, and eventually origins.
I think the next thing on my plate is to implement origins, so you can demonstrate what a fetch / pull / pull --rebase really does
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.
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.
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.
True true, I was hoping to have a complete tutorial on positioning -- what master^^ does, HEAD~4, all of that. It was on my todo list but (for the millionth time) it got submitted without my knowledge.
Open up a github issue and I'll definitely throw something up
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?
I'm using browserify[1] -- it's a great system because I can write all my code node-style, write tests that run in pure node, and then wrap all my resources for the browser! Grunt is the actual tool that I use to manage the build (it also handles things like hashing, minifying, etc).
Not OP but my feeling is that none of the git GUIs are particularly good or feature complete and I usually end up having to drop to a command line if I want to do anything interesting. That said, I really like `gitg` for its tree view and generally looking relatively nice, but I think functionality wise nothing really matches git gui and gitk, despite how ugly they are. Qgit is also kind of nice.
This. It's the only UI tool that I know that is powerful enough for everyday work, yet simple enough to understand for noobs because it can't do everything that Git can. Sometimes, you'll have to use the shell, still, if you're a power user. Which is fine!
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.
I also found this really confusing, just in general the "OSX window" design made me think I could close them, minimize them, move them, etc (which would have been really useful, especially the 'goal' window).
The app in general is supremely awesome though, I love it, I hope github hires the author to fully flesh it out and make it part of their tutorial. It is insanely useful for people whom are new to git.
Ah!! I just realized people were clicking on those silly little buttons I had on the top... I totally added them simply for design flair. For now I'll add a nasty alert that they don't actually work, but eventually it would be cool to bind them to close events...
Just a side note - I think you can monazite this if desired.
If you created a way for a company to easily define levels that mimic their typical workflow it would be a great on-boarding tool for new employees, a great interview tool and also a great reference tool for 'i need to do X, how does the company prefer I do X?'. I can definitely see this justifying a subscription fee for a lot of companies.
Awesome work! I really wish this had existed when I first learned git.
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
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"?
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.
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
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.
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. :)
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.
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.
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.
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.
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
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.
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.
It gave me the same message on my netbook (1024x600) at 100% zoom. I had to zoom out a few levels to make it happy, but then I couldn’t read the text. :(
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.
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.
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.
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
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
http://imgur.com/XvK3kFY - the layout of the box is messed up in Firefox. Using Firefox version - 18.0.2. Works great in chrome though. Thanks for the nice tutorial!
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!
No problem, really glad you like it. I think one of the most important distinctions as well is the difference between rebasing and merging -- I show this off in the demo link:
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?
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.
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.
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?
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!
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?
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!
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.
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...
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.
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.
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.
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!
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
$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.
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).
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.)
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.
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.
That would be one of the next steps. I just released an really simple MVP and got my head around other projects. I'm sure gonna refactor the thing eventually and make some things clearer.
I guess I need to rethink the whole layout. Under 'tips' there is a small explanation but might still be confusing. There's also a 'see an example' on the bottom, but I guess it's not that helpful either. Someone gave me a nice hint of doing a landing page with explanation and a huge 'start coding' button. I'll do that :)
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)
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.
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.
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!