diff --git a/src/js/git/commands.js b/src/js/git/commands.js index 43246f16..013f86bf 100644 --- a/src/js/git/commands.js +++ b/src/js/git/commands.js @@ -685,7 +685,7 @@ var commandConfig = { var refspecParts = firstArg.split(':'); source = refspecParts[0]; destination = validateBranchName(engine, refspecParts[1]); - if (source === "" && !engine.origin.refs[options.destination]) { + if (source === "" && !engine.origin.refs[destination]) { throw new GitError({ msg: intl.todo( 'cannot delete branch ' + options.destination + ' which doesnt exist' diff --git a/src/levels/index.js b/src/levels/index.js index e16594e9..a168d41c 100644 --- a/src/levels/index.js +++ b/src/levels/index.js @@ -41,7 +41,8 @@ exports.levelSequences = { require('./remote/mergeManyFeatures').level, require('./remote/tracking').level, require('./remote/pushArgs').level, - require('./remote/pushArgs2').level + require('./remote/pushArgs2').level, + require('./remote/fetchArgs').level ] }; diff --git a/src/levels/remote/fetchArgs.js b/src/levels/remote/fetchArgs.js new file mode 100644 index 00000000..1f9b4b4c --- /dev/null +++ b/src/levels/remote/fetchArgs.js @@ -0,0 +1,123 @@ +exports.level = { + "goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C6\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C7\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C3\",\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"foo\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C6\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"foo\",\"id\":\"HEAD\"}}}", + "solutionCommand": "git fetch origin master~1:foo;git checkout foo;git fetch origin foo:master;git merge master", + "startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\",\"remoteTrackingBranchID\":\"o/master\"},\"foo\":{\"target\":\"C1\",\"id\":\"foo\",\"remoteTrackingBranchID\":\"o/foo\"},\"o/master\":{\"target\":\"C1\",\"id\":\"o/master\",\"remoteTrackingBranchID\":null},\"o/foo\":{\"target\":\"C1\",\"id\":\"o/foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"},\"originTree\":{\"branches\":{\"master\":{\"target\":\"C4\",\"id\":\"master\",\"remoteTrackingBranchID\":null},\"foo\":{\"target\":\"C6\",\"id\":\"foo\",\"remoteTrackingBranchID\":null}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C3\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C1\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C5\"],\"id\":\"C6\"}},\"HEAD\":{\"target\":\"foo\",\"id\":\"HEAD\"}}}", + "name": { + "en_US": "Fetch arguments" + }, + "hint": { + "en_US": "Pay attention how the commit ids may have swapped! You can read slides again with \"help level\"" + }, + "startDialog": { + "en_US": { + "childViews": [ + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "## Git fetch arguments", + "", + "So we've just learned all about git push arguments, this cool `` parameter, and even colon refspecs (`:`). Can we use all this knowledge for `git fetch` as well?", + "", + "You betcha! The arguments for `git fetch` are actually *very, very* similar to those for `git push`. It's the same type of concepts but just applied in the opposite direction (since now you are downloading commits rather than uploading).", + "", + "Let's go over the concepts one at a time..." + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "### The `` parameter", + "", + "If you specify a place with git fetch like in the following command:", + "", + "`git fetch origin foo`", + "", + "Git will go to the `foo` branch on the remote, grab all the commits that aren't present locally, and then plop them down onto the `o/foo` branch locally.", + "", + "Let's see this in action (just as a refresher)" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "By specifying a place..." + ], + "afterMarkdowns": [ + "We download only the commits from `foo` and place them on `o/foo`" + ], + "command": "git fetch origin foo", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo 2" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "You might be wondering -- why did git plop those commits onto the `o/foo` remote branch rather than just plopping them onto my local `foo` branch? I thought the `` parameter is a place that exists both locally and on the remote?", + "", + "Well git makes a special exception in this case because you might have work on the `foo` branch that you don't want to mess up!! This ties into the earlier lesson on `git fetch` -- it doesn't update your local non-remote branches, it only downloads the commits (so you can inspect / merge them later).", + "" + ] + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "\"Well in that case, what happens if I explicitly define both the source and destination with `:`?\"", + "", + "If you feel passionate enough to fetch commits *directly* onto a local branch, then yes you can specify that with a colon refspec. You can't fetch commits onto a branch that is checked out, but otherwise git will allow this.", + "", + "Here is the only catch though -- `` is now a place on the *remote* and `` is a *local* place to put those commits. It's the exact opposite of git push, and that makes sense since we are transferring data in the opposite direction!", + "", + "That being said, developers rarely do this in practice. I'm introducing it mainly as a way to conceptualize how `fetch` and `push` are quite similar, just in opposite directions" + ] + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "Let's see this craziness in action:" + ], + "afterMarkdowns": [ + "Wow! See, git resolved `foo~1` as a place on the origin and then downloaded those commits to `bar` (which was a local branch). Notice how `foo` and `o/foo` were not updated since we specified a destination" + ], + "command": "git fetch origin foo~1:bar", + "beforeCommand": "git branch foo; git clone; git branch bar; git fakeTeamwork foo 2" + } + }, + { + "type": "GitDemonstrationView", + "options": { + "beforeMarkdowns": [ + "No args?", + "", + "If `git fetch` receives no arguments, it just downloads all the commits from the remote onto all the remote branches..." + ], + "afterMarkdowns": [ + "Pretty simple, but worth going over just once" + ], + "command": "git fetch", + "beforeCommand": "git branch foo; git clone; git fakeTeamwork foo; git fakeTeamwork master" + } + }, + { + "type": "ModalAlert", + "options": { + "markdowns": [ + "Ok, enough talking! To finish this level, fetch just the specified commits in the goal visualization. Get fancy with those commands!", + "", + "You will have to specify the source and destination for both fetch commands. Pay attention to the goal visualization since the IDs may be switched around!" + ] + } + } + ] + } + } +};