diff --git a/build/bundle.js b/build/bundle.js index 58b6bdcd..0659c794 100644 --- a/build/bundle.js +++ b/build/bundle.js @@ -16439,8 +16439,6 @@ var GitDemonstrationView = ContainedBase.extend({ var whenHaveTree = Q.defer(); HeadlessGit.getTreeQuick(this.options.beforeCommand, whenHaveTree); whenHaveTree.promise.then(_.bind(function(tree) { - console.log('the before command i got', this.options.beforeCommand); - console.log(tree, 'is what i got'); this.mainVis.gitEngine.loadTree(tree); this.mainVis.gitVisuals.refreshTreeHarsh(); }, this)); @@ -19689,7 +19687,9 @@ if (typeof window !== 'undefined' && window.location && exports.levelSequences.remote = [ require('./remote/clone').level, require('./remote/remoteBranches').level, - require('./remote/fetch').level + require('./remote/fetch').level, + require('./remote/pull').level, + require('./remote/fakeTeamwork').level ]; } @@ -23250,9 +23250,27 @@ require.define("/src/levels/remote/remoteBranches.js",function(require,module,ex "", "Remote branches reflect the _state_ of remote repositories (since you last talked to those remote repositories). They help you understand the difference between your local work and what work is public -- a critical step to take before sharing your work with others.", "", - "Remote branches have the special property that when you check them out, you are put into detached `HEAD` mode. Git does this on purpose because you can't work on these branches directly; you have to work elsewhere and then share your work with the remote (after which your remote branches will be updated).", + "Remote branches have the special property that when you check them out, you are put into detached `HEAD` mode. Git does this on purpose because you can't work on these branches directly; you have to work elsewhere and then share your work with the remote (after which your remote branches will be updated)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### What is `o/`?", "", - "That's a lot to take in, so let's see it in action." + "You maybe wondering what the leading `o/` is for on these remote branches. Well, remote branches also have a (required) naming convention -- they are displayed in the format of:", + "", + "* `/`", + "", + "Hence, if you look at a branch named `o/master`, the branch name is `master` and the name of the remote is `o`.", + "", + "Most developers actually name their main remote `origin`, not `o`. This is so common that git actually sets up your remote to be named `origin` when you `git clone` a repository.", + "", + "Unfortunately the full name of `origin` does not fit in our UI, so we use `o` as shorthand :( Just remember when you're using real git, your remote is probably going to be named `origin`!", + "", + "That's a lot to take in, so let's see this all in action." ] } }, @@ -23273,7 +23291,7 @@ require.define("/src/levels/remote/remoteBranches.js",function(require,module,ex "type": "ModalAlert", "options": { "markdowns": [ - "To finish this level, commit once off of `master` and once after checking out `o/master`. This will help drive home how remote branches behave differently" + "To finish this level, commit once off of `master` and once after checking out `o/master`. This will help drive home how remote branches behave differently, and they only update to reflect the state of the remote" ] } } @@ -23374,6 +23392,151 @@ require.define("/src/levels/remote/fetch.js",function(require,module,exports,__d }); +require.define("/src/levels/remote/pull.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C3\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\",\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git pull", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "name": { + "en_US": "Git Pullin'" + }, + "hint": { + "en_US": "Just run git pull!" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Now that we've seen how to fetch data from a remote repository with `git fetch`, lets update our work to reflect those changes!", + "", + "There are actually many ways to do this -- once you have new commits available locally, you can incorporate them as if they were just normal commits on other branches. This means you could execute commands like:", + "", + "* `git cherry-pick o/master`", + "* `git rebase o/master`", + "* `git merge o/master`", + "* etc, etc", + "", + "In fact, the workflow of *fetching* remote changes and then *merging* them is so common that git actually make a command that does both at once! That command is `git pull`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Let's first see a `fetch` and a `merge` executed sequentially" + ], + "afterMarkdowns": [ + "Boom -- we downloaded `C3` with a `fetch` and then merged in that work with `git merge origin/master`. Now our `master` branch reflects the new work from the remote (in this case, named `origin`)" + ], + "command": "git fetch; git merge o/master", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "What would happen if we used `git pull` instead?" + ], + "afterMarkdowns": [ + "The same thing! That should make it very clear that `git pull` is essentially shorthand for a `git fetch` followed by a merge of whatever branch was just fetched." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "We will explore the details of `git pull` later (including options and arguments), but for now let's try it out in the level.", + "", + "Remember -- you can actually solve this level with just `fetch` and `merge`, but it will cost you an extra command :P" + ] + } + } + ] + } + } +}; + +}); + +require.define("/src/levels/remote/fakeTeamwork.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C3\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C5\":{\"parents\":[\"C3\",\"C4\"],\"id\":\"C5\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git clone;git fakeTeamwork 2;git commit ;git pull", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", + "name": { + "en_US": "Faking Teamwork" + }, + "hint": { + "en_US": "remember you can specify the number of commits to fake" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Simulating collaboration", + "", + "So here is the tricky thing -- for some of these upcoming lessons, we need to teach you how to pull down changes that were introduced in the remote.", + "", + "That means we need to essentially \"pretend\" that the remote was updated by one of your coworkers / friends / collaborators, sometimes on a specific branch or a certain number of commits.", + "", + "In order to do this, we introduced the aptly-named command `git fakeTeamwork`! It's pretty self explanatory, let's see a demo..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "The default behavior of `fakeTeamwork` is to simply plop down a commit on master" + ], + "afterMarkdowns": [ + "There we go -- the remote was updated with a new commit, and we haven't downloaded that commit yet because we haven't run `git fetch`." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "You can also specify the number of commits or the branch by appending them to the command" + ], + "afterMarkdowns": [ + "With one command we simulated a teammate pushing three commits to the `foo` branch on our remote" + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "The upcoming levels are going to be pretty difficult, so we're asking more of you for this level.", + "", + "Go ahead and make a remote (with `git clone`), fake some changes on that remote, commit yourself, and then pull down those changes. It's like a few lessons in one!" + ] + } + } + ] + } + } +}; + +}); + require.define("/src/js/views/levelDropdownView.js",function(require,module,exports,__dirname,__filename,process,global){var _ = require('underscore'); var Q = require('q'); // horrible hack to get localStorage Backbone plugin @@ -33973,8 +34136,6 @@ var GitDemonstrationView = ContainedBase.extend({ var whenHaveTree = Q.defer(); HeadlessGit.getTreeQuick(this.options.beforeCommand, whenHaveTree); whenHaveTree.promise.then(_.bind(function(tree) { - console.log('the before command i got', this.options.beforeCommand); - console.log(tree, 'is what i got'); this.mainVis.gitEngine.loadTree(tree); this.mainVis.gitVisuals.refreshTreeHarsh(); }, this)); @@ -38806,7 +38967,9 @@ if (typeof window !== 'undefined' && window.location && exports.levelSequences.remote = [ require('./remote/clone').level, require('./remote/remoteBranches').level, - require('./remote/fetch').level + require('./remote/fetch').level, + require('./remote/pull').level, + require('./remote/fakeTeamwork').level ]; } @@ -42167,6 +42330,77 @@ require.define("/src/levels/remote/clone.js",function(require,module,exports,__d }); require("/src/levels/remote/clone.js"); +require.define("/src/levels/remote/fakeTeamwork.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C3\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C5\":{\"parents\":[\"C3\",\"C4\"],\"id\":\"C5\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git clone;git fakeTeamwork 2;git commit ;git pull", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", + "name": { + "en_US": "Faking Teamwork" + }, + "hint": { + "en_US": "remember you can specify the number of commits to fake" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Simulating collaboration", + "", + "So here is the tricky thing -- for some of these upcoming lessons, we need to teach you how to pull down changes that were introduced in the remote.", + "", + "That means we need to essentially \"pretend\" that the remote was updated by one of your coworkers / friends / collaborators, sometimes on a specific branch or a certain number of commits.", + "", + "In order to do this, we introduced the aptly-named command `git fakeTeamwork`! It's pretty self explanatory, let's see a demo..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "The default behavior of `fakeTeamwork` is to simply plop down a commit on master" + ], + "afterMarkdowns": [ + "There we go -- the remote was updated with a new commit, and we haven't downloaded that commit yet because we haven't run `git fetch`." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "You can also specify the number of commits or the branch by appending them to the command" + ], + "afterMarkdowns": [ + "With one command we simulated a teammate pushing three commits to the `foo` branch on our remote" + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "The upcoming levels are going to be pretty difficult, so we're asking more of you for this level.", + "", + "Go ahead and make a remote (with `git clone`), fake some changes on that remote, commit yourself, and then pull down those changes. It's like a few lessons in one!" + ] + } + } + ] + } + } +}; + +}); +require("/src/levels/remote/fakeTeamwork.js"); + require.define("/src/levels/remote/fetch.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"o/master\":{\"target\":\"C5\",\"id\":\"o/master\"},\"o/bugFix\":{\"target\":\"C7\",\"id\":\"o/bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\"],\"id\":\"C4\"},\"C6\":{\"parents\":[\"C3\"],\"id\":\"C6\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C7\",\"id\":\"bugFix\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C3\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"bugFix\",\"id\":\"HEAD\"}}}", "solutionCommand": "git fetch", @@ -42257,6 +42491,82 @@ require.define("/src/levels/remote/fetch.js",function(require,module,exports,__d }); require("/src/levels/remote/fetch.js"); +require.define("/src/levels/remote/pull.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C3\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\",\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git pull", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "name": { + "en_US": "Git Pullin'" + }, + "hint": { + "en_US": "Just run git pull!" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Now that we've seen how to fetch data from a remote repository with `git fetch`, lets update our work to reflect those changes!", + "", + "There are actually many ways to do this -- once you have new commits available locally, you can incorporate them as if they were just normal commits on other branches. This means you could execute commands like:", + "", + "* `git cherry-pick o/master`", + "* `git rebase o/master`", + "* `git merge o/master`", + "* etc, etc", + "", + "In fact, the workflow of *fetching* remote changes and then *merging* them is so common that git actually make a command that does both at once! That command is `git pull`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Let's first see a `fetch` and a `merge` executed sequentially" + ], + "afterMarkdowns": [ + "Boom -- we downloaded `C3` with a `fetch` and then merged in that work with `git merge origin/master`. Now our `master` branch reflects the new work from the remote (in this case, named `origin`)" + ], + "command": "git fetch; git merge o/master", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "What would happen if we used `git pull` instead?" + ], + "afterMarkdowns": [ + "The same thing! That should make it very clear that `git pull` is essentially shorthand for a `git fetch` followed by a merge of whatever branch was just fetched." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "We will explore the details of `git pull` later (including options and arguments), but for now let's try it out in the level.", + "", + "Remember -- you can actually solve this level with just `fetch` and `merge`, but it will cost you an extra command :P" + ] + } + } + ] + } + } +}; + +}); +require("/src/levels/remote/pull.js"); + require.define("/src/levels/remote/remoteBranches.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = { "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"C4\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", "solutionCommand": "git commit;git checkout o/master;git commit", @@ -42282,9 +42592,27 @@ require.define("/src/levels/remote/remoteBranches.js",function(require,module,ex "", "Remote branches reflect the _state_ of remote repositories (since you last talked to those remote repositories). They help you understand the difference between your local work and what work is public -- a critical step to take before sharing your work with others.", "", - "Remote branches have the special property that when you check them out, you are put into detached `HEAD` mode. Git does this on purpose because you can't work on these branches directly; you have to work elsewhere and then share your work with the remote (after which your remote branches will be updated).", + "Remote branches have the special property that when you check them out, you are put into detached `HEAD` mode. Git does this on purpose because you can't work on these branches directly; you have to work elsewhere and then share your work with the remote (after which your remote branches will be updated)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### What is `o/`?", "", - "That's a lot to take in, so let's see it in action." + "You maybe wondering what the leading `o/` is for on these remote branches. Well, remote branches also have a (required) naming convention -- they are displayed in the format of:", + "", + "* `/`", + "", + "Hence, if you look at a branch named `o/master`, the branch name is `master` and the name of the remote is `o`.", + "", + "Most developers actually name their main remote `origin`, not `o`. This is so common that git actually sets up your remote to be named `origin` when you `git clone` a repository.", + "", + "Unfortunately the full name of `origin` does not fit in our UI, so we use `o` as shorthand :( Just remember when you're using real git, your remote is probably going to be named `origin`!", + "", + "That's a lot to take in, so let's see this all in action." ] } }, @@ -42305,7 +42633,7 @@ require.define("/src/levels/remote/remoteBranches.js",function(require,module,ex "type": "ModalAlert", "options": { "markdowns": [ - "To finish this level, commit once off of `master` and once after checking out `o/master`. This will help drive home how remote branches behave differently" + "To finish this level, commit once off of `master` and once after checking out `o/master`. This will help drive home how remote branches behave differently, and they only update to reflect the state of the remote" ] } } diff --git a/src/js/views/gitDemonstrationView.js b/src/js/views/gitDemonstrationView.js index bdab13fc..d20569a9 100644 --- a/src/js/views/gitDemonstrationView.js +++ b/src/js/views/gitDemonstrationView.js @@ -99,8 +99,6 @@ var GitDemonstrationView = ContainedBase.extend({ var whenHaveTree = Q.defer(); HeadlessGit.getTreeQuick(this.options.beforeCommand, whenHaveTree); whenHaveTree.promise.then(_.bind(function(tree) { - console.log('the before command i got', this.options.beforeCommand); - console.log(tree, 'is what i got'); this.mainVis.gitEngine.loadTree(tree); this.mainVis.gitVisuals.refreshTreeHarsh(); }, this)); diff --git a/src/levels/index.js b/src/levels/index.js index a5176891..87c36c4f 100644 --- a/src/levels/index.js +++ b/src/levels/index.js @@ -34,7 +34,9 @@ if (typeof window !== 'undefined' && window.location && exports.levelSequences.remote = [ require('./remote/clone').level, require('./remote/remoteBranches').level, - require('./remote/fetch').level + require('./remote/fetch').level, + require('./remote/pull').level, + require('./remote/fakeTeamwork').level ]; } diff --git a/src/levels/remote/fakeTeamwork.js b/src/levels/remote/fakeTeamwork.js new file mode 100644 index 00000000..978879cd --- /dev/null +++ b/src/levels/remote/fakeTeamwork.js @@ -0,0 +1,67 @@ +exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C3\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C5\":{\"parents\":[\"C3\",\"C4\"],\"id\":\"C5\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git clone;git fakeTeamwork 2;git commit ;git pull", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}", + "name": { + "en_US": "Faking Teamwork" + }, + "hint": { + "en_US": "remember you can specify the number of commits to fake" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Simulating collaboration", + "", + "So here is the tricky thing -- for some of these upcoming lessons, we need to teach you how to pull down changes that were introduced in the remote.", + "", + "That means we need to essentially \"pretend\" that the remote was updated by one of your coworkers / friends / collaborators, sometimes on a specific branch or a certain number of commits.", + "", + "In order to do this, we introduced the aptly-named command `git fakeTeamwork`! It's pretty self explanatory, let's see a demo..." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "The default behavior of `fakeTeamwork` is to simply plop down a commit on master" + ], + "afterMarkdowns": [ + "There we go -- the remote was updated with a new commit, and we haven't downloaded that commit yet because we haven't run `git fetch`." + ], + "command": "git fakeTeamwork", + "beforeCommand": "git clone" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "You can also specify the number of commits or the branch by appending them to the command" + ], + "afterMarkdowns": [ + "With one command we simulated a teammate pushing three commits to the `foo` branch on our remote" + ], + "command": "git fakeTeamwork foo 3", + "beforeCommand": "git branch foo; git clone" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "The upcoming levels are going to be pretty difficult, so we're asking more of you for this level.", + "", + "Go ahead and make a remote (with `git clone`), fake some changes on that remote, commit yourself, and then pull down those changes. It's like a few lessons in one!" + ] + } + } + ] + } + } +}; diff --git a/src/levels/remote/pull.js b/src/levels/remote/pull.js new file mode 100644 index 00000000..4ec0a85a --- /dev/null +++ b/src/levels/remote/pull.js @@ -0,0 +1,72 @@ +exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C3\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C2\",\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git pull", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\",\"localBranchesThatTrackThis\":null},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":[\"master\"]}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C3\",\"id\":\"master\",\"remoteTrackingBranchID\":null,\"localBranchesThatTrackThis\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C3\":{\"parents\":[\"C1\"],\"id\":\"C3\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}}", + "name": { + "en_US": "Git Pullin'" + }, + "hint": { + "en_US": "Just run git pull!" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git Pull", + "", + "Now that we've seen how to fetch data from a remote repository with `git fetch`, lets update our work to reflect those changes!", + "", + "There are actually many ways to do this -- once you have new commits available locally, you can incorporate them as if they were just normal commits on other branches. This means you could execute commands like:", + "", + "* `git cherry-pick o/master`", + "* `git rebase o/master`", + "* `git merge o/master`", + "* etc, etc", + "", + "In fact, the workflow of *fetching* remote changes and then *merging* them is so common that git actually make a command that does both at once! That command is `git pull`." + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Let's first see a `fetch` and a `merge` executed sequentially" + ], + "afterMarkdowns": [ + "Boom -- we downloaded `C3` with a `fetch` and then merged in that work with `git merge origin/master`. Now our `master` branch reflects the new work from the remote (in this case, named `origin`)" + ], + "command": "git fetch; git merge o/master", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "What would happen if we used `git pull` instead?" + ], + "afterMarkdowns": [ + "The same thing! That should make it very clear that `git pull` is essentially shorthand for a `git fetch` followed by a merge of whatever branch was just fetched." + ], + "command": "git pull", + "beforeCommand": "git clone; git commit; git fakeTeamwork" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "We will explore the details of `git pull` later (including options and arguments), but for now let's try it out in the level.", + "", + "Remember -- you can actually solve this level with just `fetch` and `merge`, but it will cost you an extra command :P" + ] + } + } + ] + } + } +}; diff --git a/src/levels/remote/remoteBranches.js b/src/levels/remote/remoteBranches.js index 5abef576..60d2af01 100644 --- a/src/levels/remote/remoteBranches.js +++ b/src/levels/remote/remoteBranches.js @@ -23,9 +23,27 @@ exports.level = { "", "Remote branches reflect the _state_ of remote repositories (since you last talked to those remote repositories). They help you understand the difference between your local work and what work is public -- a critical step to take before sharing your work with others.", "", - "Remote branches have the special property that when you check them out, you are put into detached `HEAD` mode. Git does this on purpose because you can't work on these branches directly; you have to work elsewhere and then share your work with the remote (after which your remote branches will be updated).", + "Remote branches have the special property that when you check them out, you are put into detached `HEAD` mode. Git does this on purpose because you can't work on these branches directly; you have to work elsewhere and then share your work with the remote (after which your remote branches will be updated)." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### What is `o/`?", "", - "That's a lot to take in, so let's see it in action." + "You maybe wondering what the leading `o/` is for on these remote branches. Well, remote branches also have a (required) naming convention -- they are displayed in the format of:", + "", + "* `/`", + "", + "Hence, if you look at a branch named `o/master`, the branch name is `master` and the name of the remote is `o`.", + "", + "Most developers actually name their main remote `origin`, not `o`. This is so common that git actually sets up your remote to be named `origin` when you `git clone` a repository.", + "", + "Unfortunately the full name of `origin` does not fit in our UI, so we use `o` as shorthand :( Just remember when you're using real git, your remote is probably going to be named `origin`!", + "", + "That's a lot to take in, so let's see this all in action." ] } }, @@ -46,7 +64,7 @@ exports.level = { "type": "ModalAlert", "options": { "markdowns": [ - "To finish this level, commit once off of `master` and once after checking out `o/master`. This will help drive home how remote branches behave differently" + "To finish this level, commit once off of `master` and once after checking out `o/master`. This will help drive home how remote branches behave differently, and they only update to reflect the state of the remote" ] } }