mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-26 07:58:34 +02:00
BOOM two new awesome levels before rebase 9000
This commit is contained in:
parent
542d68a975
commit
d4d7fb21c7
11 changed files with 612 additions and 29 deletions
428
build/bundle.js
428
build/bundle.js
|
@ -7131,7 +7131,8 @@ commandConfig = {
|
||||||
rebase: {
|
rebase: {
|
||||||
sc: /^gr($|\s)/,
|
sc: /^gr($|\s)/,
|
||||||
options: [
|
options: [
|
||||||
'-i'
|
'-i',
|
||||||
|
'--aboveAll'
|
||||||
],
|
],
|
||||||
regex: /^git +rebase($|\s)/,
|
regex: /^git +rebase($|\s)/,
|
||||||
execute: function(engine, command) {
|
execute: function(engine, command) {
|
||||||
|
@ -7141,7 +7142,12 @@ commandConfig = {
|
||||||
if (commandOptions['-i']) {
|
if (commandOptions['-i']) {
|
||||||
var args = commandOptions['-i'];
|
var args = commandOptions['-i'];
|
||||||
command.twoArgsImpliedHead(args, ' -i');
|
command.twoArgsImpliedHead(args, ' -i');
|
||||||
engine.rebaseInteractive(args[0], args[1]);
|
engine.rebaseInteractive(
|
||||||
|
args[0],
|
||||||
|
args[1], {
|
||||||
|
aboveAll: !!commandOptions['--aboveAll']
|
||||||
|
}
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9042,7 +9048,8 @@ GitEngine.prototype.rebase = function(targetSource, currentLocation, options) {
|
||||||
return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options);
|
return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation) {
|
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, options) {
|
||||||
|
options = options || {};
|
||||||
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
||||||
// but it will look similar.
|
// but it will look similar.
|
||||||
|
|
||||||
|
@ -9114,7 +9121,8 @@ GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation)
|
||||||
// interactive rebase view will reject or resolve our promise
|
// interactive rebase view will reject or resolve our promise
|
||||||
new InteractiveRebaseView({
|
new InteractiveRebaseView({
|
||||||
deferred: deferred,
|
deferred: deferred,
|
||||||
toRebase: toRebase
|
toRebase: toRebase,
|
||||||
|
aboveAll: options.aboveAll
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -10520,6 +10528,7 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.deferred = options.deferred;
|
this.deferred = options.deferred;
|
||||||
this.rebaseMap = {};
|
this.rebaseMap = {};
|
||||||
this.entryObjMap = {};
|
this.entryObjMap = {};
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
this.rebaseEntries = new RebaseEntryCollection();
|
this.rebaseEntries = new RebaseEntryCollection();
|
||||||
options.toRebase.reverse();
|
options.toRebase.reverse();
|
||||||
|
@ -10541,10 +10550,23 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
|
|
||||||
// show the dialog holder
|
// show the dialog holder
|
||||||
this.show();
|
this.show();
|
||||||
|
|
||||||
|
if (options.aboveAll) {
|
||||||
|
// TODO fix this :(
|
||||||
|
$('#canvasHolder').css('display', 'none');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
restoreVis: function() {
|
||||||
|
// restore the absolute position canvases
|
||||||
|
$('#canvasHolder').css('display', 'inherit');
|
||||||
},
|
},
|
||||||
|
|
||||||
confirm: function() {
|
confirm: function() {
|
||||||
this.die();
|
this.die();
|
||||||
|
if (this.options.aboveAll) {
|
||||||
|
this.restoreVis();
|
||||||
|
}
|
||||||
|
|
||||||
// get our ordering
|
// get our ordering
|
||||||
var uiOrder = [];
|
var uiOrder = [];
|
||||||
|
@ -10595,6 +10617,15 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.makeButtons();
|
this.makeButtons();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
// empty array does nothing, just like in git
|
||||||
|
this.hide();
|
||||||
|
if (this.options.aboveAll) {
|
||||||
|
this.restoreVis();
|
||||||
|
}
|
||||||
|
this.deferred.resolve([]);
|
||||||
|
},
|
||||||
|
|
||||||
makeButtons: function() {
|
makeButtons: function() {
|
||||||
// control for button
|
// control for button
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
@ -10603,9 +10634,7 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.confirm();
|
this.confirm();
|
||||||
}, this))
|
}, this))
|
||||||
.fail(_.bind(function() {
|
.fail(_.bind(function() {
|
||||||
// empty array does nothing, just like in git
|
this.cancel();
|
||||||
this.hide();
|
|
||||||
this.deferred.resolve([]);
|
|
||||||
}, this))
|
}, this))
|
||||||
.done();
|
.done();
|
||||||
|
|
||||||
|
@ -18425,6 +18454,8 @@ exports.levelSequences = {
|
||||||
require('../../levels/rampup/reversingChanges').level
|
require('../../levels/rampup/reversingChanges').level
|
||||||
],
|
],
|
||||||
rebase: [
|
rebase: [
|
||||||
|
require('../../levels/rampup/cherryPick').level,
|
||||||
|
require('../../levels/rampup/interactiveRebase').level,
|
||||||
require('../../levels/rebase/manyRebases').level
|
require('../../levels/rebase/manyRebases').level
|
||||||
],
|
],
|
||||||
mixed: [
|
mixed: [
|
||||||
|
@ -18487,14 +18518,16 @@ exports.sequenceInfo = {
|
||||||
},
|
},
|
||||||
rebase: {
|
rebase: {
|
||||||
displayName: {
|
displayName: {
|
||||||
'en_US': 'Master the Rebase Luke!',
|
'en_US': 'Moving Work Around',
|
||||||
|
// INTL out of sync :(
|
||||||
'ja': 'Rebaseをモノにする',
|
'ja': 'Rebaseをモノにする',
|
||||||
'fr_FR': 'Maîtrise Rebase, Luke!',
|
'fr_FR': 'Maîtrise Rebase, Luke!',
|
||||||
'zh_CN': '精通Rebase!',
|
'zh_CN': '精通Rebase!',
|
||||||
'ko': '리베이스 완전정복!'
|
'ko': '리베이스 완전정복!'
|
||||||
},
|
},
|
||||||
about: {
|
about: {
|
||||||
'en_US': 'What is this whole rebase hotness everyone is talking about? Find out!',
|
'en_US': 'Get comfortable with modifying the source tree',
|
||||||
|
// INTL out of sync :(
|
||||||
'ja': '話題のrebaseってどんなものだろう?って人にオススメ',
|
'ja': '話題のrebaseってどんなものだろう?って人にオススメ',
|
||||||
'fr_FR': 'Qu\'est-ce que ce rebase dont tout le monde parle ? Découvrez-le !',
|
'fr_FR': 'Qu\'est-ce que ce rebase dont tout le monde parle ? Découvrez-le !',
|
||||||
'ko': '그 좋다고들 말하는 rebase에 대해 알아봅시다!',
|
'ko': '그 좋다고들 말하는 rebase에 대해 알아봅시다!',
|
||||||
|
@ -20741,6 +20774,168 @@ require.define("/levels/rampup/reversingChanges.js",function(require,module,expo
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
require.define("/levels/rampup/cherryPick.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
||||||
|
"goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22bugFix%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C5%22%2C%22id%22%3A%22side%22%7D%2C%22another%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22another%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C6%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D",
|
||||||
|
"solutionCommand": "git cherry-pick C3 C4 C7",
|
||||||
|
"compareOnlyMasterHashAgnostic": true,
|
||||||
|
"disabledMap": {
|
||||||
|
"git rebase": true
|
||||||
|
},
|
||||||
|
"startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"side\":{\"target\":\"C5\",\"id\":\"side\"},\"another\":{\"target\":\"C7\",\"id\":\"another\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C1\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}",
|
||||||
|
"name": {
|
||||||
|
"en_US": "Cherry-pick Intro"
|
||||||
|
},
|
||||||
|
"hint": {
|
||||||
|
"en_US": "git cherry-pick followed by commit names!"
|
||||||
|
},
|
||||||
|
"startDialog": {
|
||||||
|
"en_US": {
|
||||||
|
"childViews": [
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Moving Work Around",
|
||||||
|
"",
|
||||||
|
"So far we've covered the basics of git -- committing, branching, and moving around in the source tree. Just these concepts are enough to leverage 90% of the power of git repositories and cover the main needs of developers.",
|
||||||
|
"",
|
||||||
|
"That remaining 10%, however, can be quite useful during complex workflows (or when you've gotten yourself into a bind). The next concept we're going to cover is \"moving work around\" -- in other words, its a way for developers to say \"I want this work here and that work here\" in precise, eloquent, flexible ways.",
|
||||||
|
"",
|
||||||
|
"This may seem like a lot, but it's a simple concept."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Git Cherry-pick",
|
||||||
|
"",
|
||||||
|
"The first command in this series is called `git cherry-pick`. It takes on the following form:",
|
||||||
|
"",
|
||||||
|
"* `git cherry-pick <Commit1> <Commit2> <...>`",
|
||||||
|
"",
|
||||||
|
"It's a very straightforward way of saying that you would like to copy a series of commits below your current location (`HEAD`). I personally love `cherry-pick` because there is very little magic involved and it's easy to understand.",
|
||||||
|
"",
|
||||||
|
"Let's see a demo!",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GitDemonstrationView",
|
||||||
|
"options": {
|
||||||
|
"beforeMarkdowns": [
|
||||||
|
"Here's a repository where we have some work in branch `side` that we want to copy to `master`. This could be accomplished through a rebase (which we have already learned), but let's see how cherry-pick performs."
|
||||||
|
],
|
||||||
|
"afterMarkdowns": [
|
||||||
|
"That's it! We wanted commits `C2` and `C4` and git plopped them down right below us. Simple as that!"
|
||||||
|
],
|
||||||
|
"command": "git cherry-pick C2 C4",
|
||||||
|
"beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"To complete this level, simply copy some work from the three branches shown into master. You can see which commits we want by looking at the goal visualization.",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
require.define("/levels/rampup/interactiveRebase.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
||||||
|
"goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C4%27%22%2C%22id%22%3A%22master%22%7D%2C%22overHere%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22overHere%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C5%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C5%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C5%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D",
|
||||||
|
"solutionCommand": "git rebase -i overHere",
|
||||||
|
"compareOnlyMasterHashAgnostic": true,
|
||||||
|
"disabledMap": {
|
||||||
|
"git cherry-pick": true
|
||||||
|
},
|
||||||
|
"startTree": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\"},\"overHere\":{\"target\":\"C1\",\"id\":\"overHere\"}},\"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\":[\"C4\"],\"id\":\"C5\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}",
|
||||||
|
"hint": {
|
||||||
|
"en_US": "you can use either branches or relative refs (HEAD~) to specify the rebase target"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"en_US": "Interactive Rebase Intro"
|
||||||
|
},
|
||||||
|
"startDialog": {
|
||||||
|
"en_US": {
|
||||||
|
"childViews": [
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Git Interactive Rebase",
|
||||||
|
"",
|
||||||
|
"Git cherry-pick is great when you know which commits you want (_and_ you know their corresponding hashes) -- it's hard to beat the simplicity it provides.",
|
||||||
|
"",
|
||||||
|
"But what about the situation where you don't know what commits you want? Thankfully git has you covered there as well! We can use interactive rebasing for this -- it's is the best way to review a series of commits you're about to rebase.",
|
||||||
|
"",
|
||||||
|
"Let's dive into the details..."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"All interactive rebase means is using the `rebase` command with the `-i` option.",
|
||||||
|
"",
|
||||||
|
"If you include this option, git will open up a UI to show you which commits are about to be copied below the target of the rebase. It also shows their commit hashes and messages, which is great for getting a bearing on what's what.",
|
||||||
|
"",
|
||||||
|
"For \"real\" git, the UI window means opening up a file in a text editor like `vim`. For our purposes, I've built a small dialog window that behaves the same way."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"When the interactive rebase dialog opens, you have the ability to do 3 things:",
|
||||||
|
"",
|
||||||
|
"* You can reorder commits simply by changing their order in the UI (in our window this means dragging and dropping with the mouse).",
|
||||||
|
"* You can choose to completely omit some commits. This is designated by `pick` -- toggling `pick` off means you want to drop the commit.",
|
||||||
|
"* Lastly, you can squash commits. Unfortunately our levels don't support this for a few logistical reasons, so I\"ll skip over the details of this. Long story short though -- it allows you to combine commits.",
|
||||||
|
"",
|
||||||
|
"Great! Lets see an example"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GitDemonstrationView",
|
||||||
|
"options": {
|
||||||
|
"beforeMarkdowns": [
|
||||||
|
"When you hit the button, an interactive rebase window will appear. Reorder some commits around (or feel free to unpick some) and see the result!"
|
||||||
|
],
|
||||||
|
"afterMarkdowns": [
|
||||||
|
"Boom! Git copied down commits in the exact same way you specified through the UI"
|
||||||
|
],
|
||||||
|
"command": "git rebase -i HEAD~4 --aboveAll",
|
||||||
|
"beforeCommand": "git commit; git commit; git commit; git commit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"To finish this level, do an interactive rebase and achieve the order shown in the goal visualization. Remember you can always `undo` or `reset` to fix mistakes :D"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
require.define("/levels/rebase/manyRebases.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
require.define("/levels/rebase/manyRebases.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
||||||
"compareOnlyMasterHashAgnostic": true,
|
"compareOnlyMasterHashAgnostic": true,
|
||||||
"disabledMap": {
|
"disabledMap": {
|
||||||
|
@ -23549,7 +23744,8 @@ commandConfig = {
|
||||||
rebase: {
|
rebase: {
|
||||||
sc: /^gr($|\s)/,
|
sc: /^gr($|\s)/,
|
||||||
options: [
|
options: [
|
||||||
'-i'
|
'-i',
|
||||||
|
'--aboveAll'
|
||||||
],
|
],
|
||||||
regex: /^git +rebase($|\s)/,
|
regex: /^git +rebase($|\s)/,
|
||||||
execute: function(engine, command) {
|
execute: function(engine, command) {
|
||||||
|
@ -23559,7 +23755,12 @@ commandConfig = {
|
||||||
if (commandOptions['-i']) {
|
if (commandOptions['-i']) {
|
||||||
var args = commandOptions['-i'];
|
var args = commandOptions['-i'];
|
||||||
command.twoArgsImpliedHead(args, ' -i');
|
command.twoArgsImpliedHead(args, ' -i');
|
||||||
engine.rebaseInteractive(args[0], args[1]);
|
engine.rebaseInteractive(
|
||||||
|
args[0],
|
||||||
|
args[1], {
|
||||||
|
aboveAll: !!commandOptions['--aboveAll']
|
||||||
|
}
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25837,7 +26038,8 @@ GitEngine.prototype.rebase = function(targetSource, currentLocation, options) {
|
||||||
return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options);
|
return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation) {
|
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, options) {
|
||||||
|
options = options || {};
|
||||||
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
||||||
// but it will look similar.
|
// but it will look similar.
|
||||||
|
|
||||||
|
@ -25909,7 +26111,8 @@ GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation)
|
||||||
// interactive rebase view will reject or resolve our promise
|
// interactive rebase view will reject or resolve our promise
|
||||||
new InteractiveRebaseView({
|
new InteractiveRebaseView({
|
||||||
deferred: deferred,
|
deferred: deferred,
|
||||||
toRebase: toRebase
|
toRebase: toRebase,
|
||||||
|
aboveAll: options.aboveAll
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32786,6 +32989,7 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.deferred = options.deferred;
|
this.deferred = options.deferred;
|
||||||
this.rebaseMap = {};
|
this.rebaseMap = {};
|
||||||
this.entryObjMap = {};
|
this.entryObjMap = {};
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
this.rebaseEntries = new RebaseEntryCollection();
|
this.rebaseEntries = new RebaseEntryCollection();
|
||||||
options.toRebase.reverse();
|
options.toRebase.reverse();
|
||||||
|
@ -32807,10 +33011,23 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
|
|
||||||
// show the dialog holder
|
// show the dialog holder
|
||||||
this.show();
|
this.show();
|
||||||
|
|
||||||
|
if (options.aboveAll) {
|
||||||
|
// TODO fix this :(
|
||||||
|
$('#canvasHolder').css('display', 'none');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
restoreVis: function() {
|
||||||
|
// restore the absolute position canvases
|
||||||
|
$('#canvasHolder').css('display', 'inherit');
|
||||||
},
|
},
|
||||||
|
|
||||||
confirm: function() {
|
confirm: function() {
|
||||||
this.die();
|
this.die();
|
||||||
|
if (this.options.aboveAll) {
|
||||||
|
this.restoreVis();
|
||||||
|
}
|
||||||
|
|
||||||
// get our ordering
|
// get our ordering
|
||||||
var uiOrder = [];
|
var uiOrder = [];
|
||||||
|
@ -32861,6 +33078,15 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.makeButtons();
|
this.makeButtons();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
// empty array does nothing, just like in git
|
||||||
|
this.hide();
|
||||||
|
if (this.options.aboveAll) {
|
||||||
|
this.restoreVis();
|
||||||
|
}
|
||||||
|
this.deferred.resolve([]);
|
||||||
|
},
|
||||||
|
|
||||||
makeButtons: function() {
|
makeButtons: function() {
|
||||||
// control for button
|
// control for button
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
@ -32869,9 +33095,7 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.confirm();
|
this.confirm();
|
||||||
}, this))
|
}, this))
|
||||||
.fail(_.bind(function() {
|
.fail(_.bind(function() {
|
||||||
// empty array does nothing, just like in git
|
this.cancel();
|
||||||
this.hide();
|
|
||||||
this.deferred.resolve([]);
|
|
||||||
}, this))
|
}, this))
|
||||||
.done();
|
.done();
|
||||||
|
|
||||||
|
@ -35933,6 +36157,8 @@ exports.levelSequences = {
|
||||||
require('../../levels/rampup/reversingChanges').level
|
require('../../levels/rampup/reversingChanges').level
|
||||||
],
|
],
|
||||||
rebase: [
|
rebase: [
|
||||||
|
require('../../levels/rampup/cherryPick').level,
|
||||||
|
require('../../levels/rampup/interactiveRebase').level,
|
||||||
require('../../levels/rebase/manyRebases').level
|
require('../../levels/rebase/manyRebases').level
|
||||||
],
|
],
|
||||||
mixed: [
|
mixed: [
|
||||||
|
@ -35995,14 +36221,16 @@ exports.sequenceInfo = {
|
||||||
},
|
},
|
||||||
rebase: {
|
rebase: {
|
||||||
displayName: {
|
displayName: {
|
||||||
'en_US': 'Master the Rebase Luke!',
|
'en_US': 'Moving Work Around',
|
||||||
|
// INTL out of sync :(
|
||||||
'ja': 'Rebaseをモノにする',
|
'ja': 'Rebaseをモノにする',
|
||||||
'fr_FR': 'Maîtrise Rebase, Luke!',
|
'fr_FR': 'Maîtrise Rebase, Luke!',
|
||||||
'zh_CN': '精通Rebase!',
|
'zh_CN': '精通Rebase!',
|
||||||
'ko': '리베이스 완전정복!'
|
'ko': '리베이스 완전정복!'
|
||||||
},
|
},
|
||||||
about: {
|
about: {
|
||||||
'en_US': 'What is this whole rebase hotness everyone is talking about? Find out!',
|
'en_US': 'Get comfortable with modifying the source tree',
|
||||||
|
// INTL out of sync :(
|
||||||
'ja': '話題のrebaseってどんなものだろう?って人にオススメ',
|
'ja': '話題のrebaseってどんなものだろう?って人にオススメ',
|
||||||
'fr_FR': 'Qu\'est-ce que ce rebase dont tout le monde parle ? Découvrez-le !',
|
'fr_FR': 'Qu\'est-ce que ce rebase dont tout le monde parle ? Découvrez-le !',
|
||||||
'ko': '그 좋다고들 말하는 rebase에 대해 알아봅시다!',
|
'ko': '그 좋다고들 말하는 rebase에 대해 알아봅시다!',
|
||||||
|
@ -38042,6 +38270,84 @@ require.define("/src/levels/mixed/jugglingCommits2.js",function(require,module,e
|
||||||
});
|
});
|
||||||
require("/src/levels/mixed/jugglingCommits2.js");
|
require("/src/levels/mixed/jugglingCommits2.js");
|
||||||
|
|
||||||
|
require.define("/src/levels/rampup/cherryPick.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
||||||
|
"goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22bugFix%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C5%22%2C%22id%22%3A%22side%22%7D%2C%22another%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22another%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C6%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D",
|
||||||
|
"solutionCommand": "git cherry-pick C3 C4 C7",
|
||||||
|
"compareOnlyMasterHashAgnostic": true,
|
||||||
|
"disabledMap": {
|
||||||
|
"git rebase": true
|
||||||
|
},
|
||||||
|
"startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"side\":{\"target\":\"C5\",\"id\":\"side\"},\"another\":{\"target\":\"C7\",\"id\":\"another\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C1\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}",
|
||||||
|
"name": {
|
||||||
|
"en_US": "Cherry-pick Intro"
|
||||||
|
},
|
||||||
|
"hint": {
|
||||||
|
"en_US": "git cherry-pick followed by commit names!"
|
||||||
|
},
|
||||||
|
"startDialog": {
|
||||||
|
"en_US": {
|
||||||
|
"childViews": [
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Moving Work Around",
|
||||||
|
"",
|
||||||
|
"So far we've covered the basics of git -- committing, branching, and moving around in the source tree. Just these concepts are enough to leverage 90% of the power of git repositories and cover the main needs of developers.",
|
||||||
|
"",
|
||||||
|
"That remaining 10%, however, can be quite useful during complex workflows (or when you've gotten yourself into a bind). The next concept we're going to cover is \"moving work around\" -- in other words, its a way for developers to say \"I want this work here and that work here\" in precise, eloquent, flexible ways.",
|
||||||
|
"",
|
||||||
|
"This may seem like a lot, but it's a simple concept."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Git Cherry-pick",
|
||||||
|
"",
|
||||||
|
"The first command in this series is called `git cherry-pick`. It takes on the following form:",
|
||||||
|
"",
|
||||||
|
"* `git cherry-pick <Commit1> <Commit2> <...>`",
|
||||||
|
"",
|
||||||
|
"It's a very straightforward way of saying that you would like to copy a series of commits below your current location (`HEAD`). I personally love `cherry-pick` because there is very little magic involved and it's easy to understand.",
|
||||||
|
"",
|
||||||
|
"Let's see a demo!",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GitDemonstrationView",
|
||||||
|
"options": {
|
||||||
|
"beforeMarkdowns": [
|
||||||
|
"Here's a repository where we have some work in branch `side` that we want to copy to `master`. This could be accomplished through a rebase (which we have already learned), but let's see how cherry-pick performs."
|
||||||
|
],
|
||||||
|
"afterMarkdowns": [
|
||||||
|
"That's it! We wanted commits `C2` and `C4` and git plopped them down right below us. Simple as that!"
|
||||||
|
],
|
||||||
|
"command": "git cherry-pick C2 C4",
|
||||||
|
"beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"To complete this level, simply copy some work from the three branches shown into master. You can see which commits we want by looking at the goal visualization.",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
require("/src/levels/rampup/cherryPick.js");
|
||||||
|
|
||||||
require.define("/src/levels/rampup/detachedHead.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
require.define("/src/levels/rampup/detachedHead.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
||||||
"goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"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\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"C4\",\"id\":\"HEAD\"}}",
|
"goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"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\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"C4\",\"id\":\"HEAD\"}}",
|
||||||
"solutionCommand": "git checkout C4",
|
"solutionCommand": "git checkout C4",
|
||||||
|
@ -38217,6 +38523,92 @@ require.define("/src/levels/rampup/detachedHead.js",function(require,module,expo
|
||||||
});
|
});
|
||||||
require("/src/levels/rampup/detachedHead.js");
|
require("/src/levels/rampup/detachedHead.js");
|
||||||
|
|
||||||
|
require.define("/src/levels/rampup/interactiveRebase.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
||||||
|
"goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C4%27%22%2C%22id%22%3A%22master%22%7D%2C%22overHere%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22overHere%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C5%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C5%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C5%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D",
|
||||||
|
"solutionCommand": "git rebase -i overHere",
|
||||||
|
"compareOnlyMasterHashAgnostic": true,
|
||||||
|
"disabledMap": {
|
||||||
|
"git cherry-pick": true
|
||||||
|
},
|
||||||
|
"startTree": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\"},\"overHere\":{\"target\":\"C1\",\"id\":\"overHere\"}},\"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\":[\"C4\"],\"id\":\"C5\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}",
|
||||||
|
"hint": {
|
||||||
|
"en_US": "you can use either branches or relative refs (HEAD~) to specify the rebase target"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"en_US": "Interactive Rebase Intro"
|
||||||
|
},
|
||||||
|
"startDialog": {
|
||||||
|
"en_US": {
|
||||||
|
"childViews": [
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Git Interactive Rebase",
|
||||||
|
"",
|
||||||
|
"Git cherry-pick is great when you know which commits you want (_and_ you know their corresponding hashes) -- it's hard to beat the simplicity it provides.",
|
||||||
|
"",
|
||||||
|
"But what about the situation where you don't know what commits you want? Thankfully git has you covered there as well! We can use interactive rebasing for this -- it's is the best way to review a series of commits you're about to rebase.",
|
||||||
|
"",
|
||||||
|
"Let's dive into the details..."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"All interactive rebase means is using the `rebase` command with the `-i` option.",
|
||||||
|
"",
|
||||||
|
"If you include this option, git will open up a UI to show you which commits are about to be copied below the target of the rebase. It also shows their commit hashes and messages, which is great for getting a bearing on what's what.",
|
||||||
|
"",
|
||||||
|
"For \"real\" git, the UI window means opening up a file in a text editor like `vim`. For our purposes, I've built a small dialog window that behaves the same way."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"When the interactive rebase dialog opens, you have the ability to do 3 things:",
|
||||||
|
"",
|
||||||
|
"* You can reorder commits simply by changing their order in the UI (in our window this means dragging and dropping with the mouse).",
|
||||||
|
"* You can choose to completely omit some commits. This is designated by `pick` -- toggling `pick` off means you want to drop the commit.",
|
||||||
|
"* Lastly, you can squash commits. Unfortunately our levels don't support this for a few logistical reasons, so I\"ll skip over the details of this. Long story short though -- it allows you to combine commits.",
|
||||||
|
"",
|
||||||
|
"Great! Lets see an example"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GitDemonstrationView",
|
||||||
|
"options": {
|
||||||
|
"beforeMarkdowns": [
|
||||||
|
"When you hit the button, an interactive rebase window will appear. Reorder some commits around (or feel free to unpick some) and see the result!"
|
||||||
|
],
|
||||||
|
"afterMarkdowns": [
|
||||||
|
"Boom! Git copied down commits in the exact same way you specified through the UI"
|
||||||
|
],
|
||||||
|
"command": "git rebase -i HEAD~4 --aboveAll",
|
||||||
|
"beforeCommand": "git commit; git commit; git commit; git commit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"To finish this level, do an interactive rebase and achieve the order shown in the goal visualization. Remember you can always `undo` or `reset` to fix mistakes :D"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
});
|
||||||
|
require("/src/levels/rampup/interactiveRebase.js");
|
||||||
|
|
||||||
require.define("/src/levels/rampup/relativeRefs.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
require.define("/src/levels/rampup/relativeRefs.js",function(require,module,exports,__dirname,__filename,process,global){exports.level = {
|
||||||
"goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"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\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"C3\",\"id\":\"HEAD\"}}",
|
"goalTreeString": "{\"branches\":{\"master\":{\"target\":\"C2\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C4\",\"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\":[\"C3\"],\"id\":\"C4\"}},\"HEAD\":{\"target\":\"C3\",\"id\":\"HEAD\"}}",
|
||||||
"solutionCommand": "git checkout bugFix^",
|
"solutionCommand": "git checkout bugFix^",
|
||||||
|
|
1
build/bundle.min.1a803a3b.js
Normal file
1
build/bundle.min.1a803a3b.js
Normal file
File diff suppressed because one or more lines are too long
1
build/bundle.min.js
vendored
Normal file
1
build/bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -439,7 +439,7 @@
|
||||||
For a much easier time perusing the source, see the individual files at:
|
For a much easier time perusing the source, see the individual files at:
|
||||||
https://github.com/pcottle/learnGitBranching
|
https://github.com/pcottle/learnGitBranching
|
||||||
-->
|
-->
|
||||||
<script src="build/bundle.js"></script>
|
<script src="build/bundle.min.1a803a3b.js"></script>
|
||||||
|
|
||||||
<!-- The advantage of github pages: super-easy, simple, slick static hostic.
|
<!-- The advantage of github pages: super-easy, simple, slick static hostic.
|
||||||
The downside? No raw logs to parse for analytics, so I have to include
|
The downside? No raw logs to parse for analytics, so I have to include
|
||||||
|
|
|
@ -413,7 +413,8 @@ commandConfig = {
|
||||||
rebase: {
|
rebase: {
|
||||||
sc: /^gr($|\s)/,
|
sc: /^gr($|\s)/,
|
||||||
options: [
|
options: [
|
||||||
'-i'
|
'-i',
|
||||||
|
'--aboveAll'
|
||||||
],
|
],
|
||||||
regex: /^git +rebase($|\s)/,
|
regex: /^git +rebase($|\s)/,
|
||||||
execute: function(engine, command) {
|
execute: function(engine, command) {
|
||||||
|
@ -423,7 +424,12 @@ commandConfig = {
|
||||||
if (commandOptions['-i']) {
|
if (commandOptions['-i']) {
|
||||||
var args = commandOptions['-i'];
|
var args = commandOptions['-i'];
|
||||||
command.twoArgsImpliedHead(args, ' -i');
|
command.twoArgsImpliedHead(args, ' -i');
|
||||||
engine.rebaseInteractive(args[0], args[1]);
|
engine.rebaseInteractive(
|
||||||
|
args[0],
|
||||||
|
args[1], {
|
||||||
|
aboveAll: !!commandOptions['--aboveAll']
|
||||||
|
}
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1397,7 +1397,8 @@ GitEngine.prototype.rebase = function(targetSource, currentLocation, options) {
|
||||||
return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options);
|
return this.rebaseFinish(toRebaseRough, stopSet, targetSource, currentLocation, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation) {
|
GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation, options) {
|
||||||
|
options = options || {};
|
||||||
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
// there are a reduced set of checks now, so we can't exactly use parts of the rebase function
|
||||||
// but it will look similar.
|
// but it will look similar.
|
||||||
|
|
||||||
|
@ -1469,7 +1470,8 @@ GitEngine.prototype.rebaseInteractive = function(targetSource, currentLocation)
|
||||||
// interactive rebase view will reject or resolve our promise
|
// interactive rebase view will reject or resolve our promise
|
||||||
new InteractiveRebaseView({
|
new InteractiveRebaseView({
|
||||||
deferred: deferred,
|
deferred: deferred,
|
||||||
toRebase: toRebase
|
toRebase: toRebase,
|
||||||
|
aboveAll: options.aboveAll
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.deferred = options.deferred;
|
this.deferred = options.deferred;
|
||||||
this.rebaseMap = {};
|
this.rebaseMap = {};
|
||||||
this.entryObjMap = {};
|
this.entryObjMap = {};
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
this.rebaseEntries = new RebaseEntryCollection();
|
this.rebaseEntries = new RebaseEntryCollection();
|
||||||
options.toRebase.reverse();
|
options.toRebase.reverse();
|
||||||
|
@ -38,10 +39,23 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
|
|
||||||
// show the dialog holder
|
// show the dialog holder
|
||||||
this.show();
|
this.show();
|
||||||
|
|
||||||
|
if (options.aboveAll) {
|
||||||
|
// TODO fix this :(
|
||||||
|
$('#canvasHolder').css('display', 'none');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
restoreVis: function() {
|
||||||
|
// restore the absolute position canvases
|
||||||
|
$('#canvasHolder').css('display', 'inherit');
|
||||||
},
|
},
|
||||||
|
|
||||||
confirm: function() {
|
confirm: function() {
|
||||||
this.die();
|
this.die();
|
||||||
|
if (this.options.aboveAll) {
|
||||||
|
this.restoreVis();
|
||||||
|
}
|
||||||
|
|
||||||
// get our ordering
|
// get our ordering
|
||||||
var uiOrder = [];
|
var uiOrder = [];
|
||||||
|
@ -92,6 +106,15 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.makeButtons();
|
this.makeButtons();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cancel: function() {
|
||||||
|
// empty array does nothing, just like in git
|
||||||
|
this.hide();
|
||||||
|
if (this.options.aboveAll) {
|
||||||
|
this.restoreVis();
|
||||||
|
}
|
||||||
|
this.deferred.resolve([]);
|
||||||
|
},
|
||||||
|
|
||||||
makeButtons: function() {
|
makeButtons: function() {
|
||||||
// control for button
|
// control for button
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
|
@ -100,9 +123,7 @@ var InteractiveRebaseView = ContainedBase.extend({
|
||||||
this.confirm();
|
this.confirm();
|
||||||
}, this))
|
}, this))
|
||||||
.fail(_.bind(function() {
|
.fail(_.bind(function() {
|
||||||
// empty array does nothing, just like in git
|
this.cancel();
|
||||||
this.hide();
|
|
||||||
this.deferred.resolve([]);
|
|
||||||
}, this))
|
}, this))
|
||||||
.done();
|
.done();
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@ exports.levelSequences = {
|
||||||
require('../../levels/rampup/reversingChanges').level
|
require('../../levels/rampup/reversingChanges').level
|
||||||
],
|
],
|
||||||
rebase: [
|
rebase: [
|
||||||
|
require('../../levels/rampup/cherryPick').level,
|
||||||
|
require('../../levels/rampup/interactiveRebase').level,
|
||||||
require('../../levels/rebase/manyRebases').level
|
require('../../levels/rebase/manyRebases').level
|
||||||
],
|
],
|
||||||
mixed: [
|
mixed: [
|
||||||
|
@ -76,14 +78,16 @@ exports.sequenceInfo = {
|
||||||
},
|
},
|
||||||
rebase: {
|
rebase: {
|
||||||
displayName: {
|
displayName: {
|
||||||
'en_US': 'Master the Rebase Luke!',
|
'en_US': 'Moving Work Around',
|
||||||
|
// INTL out of sync :(
|
||||||
'ja': 'Rebaseをモノにする',
|
'ja': 'Rebaseをモノにする',
|
||||||
'fr_FR': 'Maîtrise Rebase, Luke!',
|
'fr_FR': 'Maîtrise Rebase, Luke!',
|
||||||
'zh_CN': '精通Rebase!',
|
'zh_CN': '精通Rebase!',
|
||||||
'ko': '리베이스 완전정복!'
|
'ko': '리베이스 완전정복!'
|
||||||
},
|
},
|
||||||
about: {
|
about: {
|
||||||
'en_US': 'What is this whole rebase hotness everyone is talking about? Find out!',
|
'en_US': 'Get comfortable with modifying the source tree',
|
||||||
|
// INTL out of sync :(
|
||||||
'ja': '話題のrebaseってどんなものだろう?って人にオススメ',
|
'ja': '話題のrebaseってどんなものだろう?って人にオススメ',
|
||||||
'fr_FR': 'Qu\'est-ce que ce rebase dont tout le monde parle ? Découvrez-le !',
|
'fr_FR': 'Qu\'est-ce que ce rebase dont tout le monde parle ? Découvrez-le !',
|
||||||
'ko': '그 좋다고들 말하는 rebase에 대해 알아봅시다!',
|
'ko': '그 좋다고들 말하는 rebase에 대해 알아봅시다!',
|
||||||
|
|
74
src/levels/rampup/cherryPick.js
Normal file
74
src/levels/rampup/cherryPick.js
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
exports.level = {
|
||||||
|
"goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C7%27%22%2C%22id%22%3A%22master%22%7D%2C%22bugFix%22%3A%7B%22target%22%3A%22C3%22%2C%22id%22%3A%22bugFix%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C5%22%2C%22id%22%3A%22side%22%7D%2C%22another%22%3A%7B%22target%22%3A%22C7%22%2C%22id%22%3A%22another%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C6%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C6%22%7D%2C%22C7%22%3A%7B%22parents%22%3A%5B%22C6%22%5D%2C%22id%22%3A%22C7%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%2C%22C7%27%22%3A%7B%22parents%22%3A%5B%22C4%27%22%5D%2C%22id%22%3A%22C7%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D",
|
||||||
|
"solutionCommand": "git cherry-pick C3 C4 C7",
|
||||||
|
"compareOnlyMasterHashAgnostic": true,
|
||||||
|
"disabledMap": {
|
||||||
|
"git rebase": true
|
||||||
|
},
|
||||||
|
"startTree": "{\"branches\":{\"master\":{\"target\":\"C1\",\"id\":\"master\"},\"bugFix\":{\"target\":\"C3\",\"id\":\"bugFix\"},\"side\":{\"target\":\"C5\",\"id\":\"side\"},\"another\":{\"target\":\"C7\",\"id\":\"another\"}},\"commits\":{\"C0\":{\"parents\":[],\"id\":\"C0\",\"rootCommit\":true},\"C1\":{\"parents\":[\"C0\"],\"id\":\"C1\"},\"C2\":{\"parents\":[\"C1\"],\"id\":\"C2\"},\"C3\":{\"parents\":[\"C2\"],\"id\":\"C3\"},\"C4\":{\"parents\":[\"C1\"],\"id\":\"C4\"},\"C5\":{\"parents\":[\"C4\"],\"id\":\"C5\"},\"C6\":{\"parents\":[\"C1\"],\"id\":\"C6\"},\"C7\":{\"parents\":[\"C6\"],\"id\":\"C7\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}",
|
||||||
|
"name": {
|
||||||
|
"en_US": "Cherry-pick Intro"
|
||||||
|
},
|
||||||
|
"hint": {
|
||||||
|
"en_US": "git cherry-pick followed by commit names!"
|
||||||
|
},
|
||||||
|
"startDialog": {
|
||||||
|
"en_US": {
|
||||||
|
"childViews": [
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Moving Work Around",
|
||||||
|
"",
|
||||||
|
"So far we've covered the basics of git -- committing, branching, and moving around in the source tree. Just these concepts are enough to leverage 90% of the power of git repositories and cover the main needs of developers.",
|
||||||
|
"",
|
||||||
|
"That remaining 10%, however, can be quite useful during complex workflows (or when you've gotten yourself into a bind). The next concept we're going to cover is \"moving work around\" -- in other words, its a way for developers to say \"I want this work here and that work here\" in precise, eloquent, flexible ways.",
|
||||||
|
"",
|
||||||
|
"This may seem like a lot, but it's a simple concept."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Git Cherry-pick",
|
||||||
|
"",
|
||||||
|
"The first command in this series is called `git cherry-pick`. It takes on the following form:",
|
||||||
|
"",
|
||||||
|
"* `git cherry-pick <Commit1> <Commit2> <...>`",
|
||||||
|
"",
|
||||||
|
"It's a very straightforward way of saying that you would like to copy a series of commits below your current location (`HEAD`). I personally love `cherry-pick` because there is very little magic involved and it's easy to understand.",
|
||||||
|
"",
|
||||||
|
"Let's see a demo!",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GitDemonstrationView",
|
||||||
|
"options": {
|
||||||
|
"beforeMarkdowns": [
|
||||||
|
"Here's a repository where we have some work in branch `side` that we want to copy to `master`. This could be accomplished through a rebase (which we have already learned), but let's see how cherry-pick performs."
|
||||||
|
],
|
||||||
|
"afterMarkdowns": [
|
||||||
|
"That's it! We wanted commits `C2` and `C4` and git plopped them down right below us. Simple as that!"
|
||||||
|
],
|
||||||
|
"command": "git cherry-pick C2 C4",
|
||||||
|
"beforeCommand": "git checkout -b side; git commit; git commit; git commit; git checkout master; git commit;"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"To complete this level, simply copy some work from the three branches shown into master. You can see which commits we want by looking at the goal visualization.",
|
||||||
|
""
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
82
src/levels/rampup/interactiveRebase.js
Normal file
82
src/levels/rampup/interactiveRebase.js
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
exports.level = {
|
||||||
|
"goalTreeString": "%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C4%27%22%2C%22id%22%3A%22master%22%7D%2C%22overHere%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22overHere%22%7D%7D%2C%22commits%22%3A%7B%22C0%22%3A%7B%22parents%22%3A%5B%5D%2C%22id%22%3A%22C0%22%2C%22rootCommit%22%3Atrue%7D%2C%22C1%22%3A%7B%22parents%22%3A%5B%22C0%22%5D%2C%22id%22%3A%22C1%22%7D%2C%22C2%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C3%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C3%22%7D%2C%22C4%22%3A%7B%22parents%22%3A%5B%22C3%22%5D%2C%22id%22%3A%22C4%22%7D%2C%22C5%22%3A%7B%22parents%22%3A%5B%22C4%22%5D%2C%22id%22%3A%22C5%22%7D%2C%22C3%27%22%3A%7B%22parents%22%3A%5B%22C1%22%5D%2C%22id%22%3A%22C3%27%22%7D%2C%22C5%27%22%3A%7B%22parents%22%3A%5B%22C3%27%22%5D%2C%22id%22%3A%22C5%27%22%7D%2C%22C4%27%22%3A%7B%22parents%22%3A%5B%22C5%27%22%5D%2C%22id%22%3A%22C4%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22master%22%2C%22id%22%3A%22HEAD%22%7D%7D",
|
||||||
|
"solutionCommand": "git rebase -i overHere",
|
||||||
|
"compareOnlyMasterHashAgnostic": true,
|
||||||
|
"disabledMap": {
|
||||||
|
"git cherry-pick": true
|
||||||
|
},
|
||||||
|
"startTree": "{\"branches\":{\"master\":{\"target\":\"C5\",\"id\":\"master\"},\"overHere\":{\"target\":\"C1\",\"id\":\"overHere\"}},\"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\":[\"C4\"],\"id\":\"C5\"}},\"HEAD\":{\"target\":\"master\",\"id\":\"HEAD\"}}",
|
||||||
|
"hint": {
|
||||||
|
"en_US": "you can use either branches or relative refs (HEAD~) to specify the rebase target"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"en_US": "Interactive Rebase Intro"
|
||||||
|
},
|
||||||
|
"startDialog": {
|
||||||
|
"en_US": {
|
||||||
|
"childViews": [
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"## Git Interactive Rebase",
|
||||||
|
"",
|
||||||
|
"Git cherry-pick is great when you know which commits you want (_and_ you know their corresponding hashes) -- it's hard to beat the simplicity it provides.",
|
||||||
|
"",
|
||||||
|
"But what about the situation where you don't know what commits you want? Thankfully git has you covered there as well! We can use interactive rebasing for this -- it's is the best way to review a series of commits you're about to rebase.",
|
||||||
|
"",
|
||||||
|
"Let's dive into the details..."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"All interactive rebase means is using the `rebase` command with the `-i` option.",
|
||||||
|
"",
|
||||||
|
"If you include this option, git will open up a UI to show you which commits are about to be copied below the target of the rebase. It also shows their commit hashes and messages, which is great for getting a bearing on what's what.",
|
||||||
|
"",
|
||||||
|
"For \"real\" git, the UI window means opening up a file in a text editor like `vim`. For our purposes, I've built a small dialog window that behaves the same way."
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"When the interactive rebase dialog opens, you have the ability to do 3 things:",
|
||||||
|
"",
|
||||||
|
"* You can reorder commits simply by changing their order in the UI (in our window this means dragging and dropping with the mouse).",
|
||||||
|
"* You can choose to completely omit some commits. This is designated by `pick` -- toggling `pick` off means you want to drop the commit.",
|
||||||
|
"* Lastly, you can squash commits. Unfortunately our levels don't support this for a few logistical reasons, so I\"ll skip over the details of this. Long story short though -- it allows you to combine commits.",
|
||||||
|
"",
|
||||||
|
"Great! Lets see an example"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "GitDemonstrationView",
|
||||||
|
"options": {
|
||||||
|
"beforeMarkdowns": [
|
||||||
|
"When you hit the button, an interactive rebase window will appear. Reorder some commits around (or feel free to unpick some) and see the result!"
|
||||||
|
],
|
||||||
|
"afterMarkdowns": [
|
||||||
|
"Boom! Git copied down commits in the exact same way you specified through the UI"
|
||||||
|
],
|
||||||
|
"command": "git rebase -i HEAD~4 --aboveAll",
|
||||||
|
"beforeCommand": "git commit; git commit; git commit; git commit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ModalAlert",
|
||||||
|
"options": {
|
||||||
|
"markdowns": [
|
||||||
|
"To finish this level, do an interactive rebase and achieve the order shown in the goal visualization. Remember you can always `undo` or `reset` to fix mistakes :D"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
2
todo.txt
2
todo.txt
|
@ -13,7 +13,6 @@ Easier origin things:
|
||||||
- getRemoteBranch has a default (the same name of the branch) but could be different
|
- getRemoteBranch has a default (the same name of the branch) but could be different
|
||||||
- git push takes in an argument, and has to check if the remote branch exists, and makes
|
- git push takes in an argument, and has to check if the remote branch exists, and makes
|
||||||
it otherwise (after pushing)
|
it otherwise (after pushing)
|
||||||
[ ] finally work on an upload / download animation
|
|
||||||
|
|
||||||
Origin things:
|
Origin things:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -42,6 +41,7 @@ Ideas for cleaning
|
||||||
Done things:
|
Done things:
|
||||||
(I only started this on Dec 17th 2012 to get a better sense of what was done)
|
(I only started this on Dec 17th 2012 to get a better sense of what was done)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
[x] finally work on an upload / download animation
|
||||||
[x] factor out golf thing too
|
[x] factor out golf thing too
|
||||||
[x] factor regexes and instant commands into one module
|
[x] factor regexes and instant commands into one module
|
||||||
[x] big command refactor to get everything in one place
|
[x] big command refactor to get everything in one place
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue