mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-07-03 19:24:29 +02:00
big commands refactor in prep for hackathon
This commit is contained in:
parent
5ec8a2916f
commit
e422bdb181
11 changed files with 1071 additions and 1077 deletions
1541
build/bundle.js
1541
build/bundle.js
File diff suppressed because it is too large
Load diff
1
build/bundle.min.f16f04ad.js
Normal file
1
build/bundle.min.f16f04ad.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
1
grunt.js
1
grunt.js
|
@ -157,6 +157,7 @@ module.exports = function(grunt) {
|
||||||
runs: true,
|
runs: true,
|
||||||
waitsFor: true,
|
waitsFor: true,
|
||||||
exports: true,
|
exports: true,
|
||||||
|
module: true,
|
||||||
process: true
|
process: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -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.f16f04ad.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
|
||||||
|
|
|
@ -29,7 +29,8 @@ var expectTreeAsync = function(command, expectedJSON) {
|
||||||
if (diff > TIME - 50 && !haveReported) {
|
if (diff > TIME - 50 && !haveReported) {
|
||||||
haveReported = true;
|
haveReported = true;
|
||||||
console.log('not going to match', command);
|
console.log('not going to match', command);
|
||||||
console.log('expected', loadTree(expectedJSON), 'actual', headless.gitEngine.exportTree());
|
console.log('expected\n>>>>>>>>\n', loadTree(expectedJSON));
|
||||||
|
console.log('\n<<<<<<<<<<<\nactual', headless.gitEngine.exportTree());
|
||||||
}
|
}
|
||||||
return compareAnswer(headless, expectedJSON);
|
return compareAnswer(headless, expectedJSON);
|
||||||
}, 'trees should be equal', 100);
|
}, 'trees should be equal', 100);
|
||||||
|
@ -57,6 +58,27 @@ describe('GitEngine', function() {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('handles branch options', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'git branch banana C0; git commit; git checkout -b side banana; git branch -d banana;git branch -f another C1; git commit',
|
||||||
|
'{"branches":{"master":{"target":"C2","id":"master"},"side":{"target":"C3","id":"side"},"another":{"target":"C1","id":"another"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C0"],"id":"C3"}},"HEAD":{"target":"side","id":"HEAD"}}'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does add', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'git add; git commit',
|
||||||
|
oneCommit
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('resets with all options', function() {
|
||||||
|
expectTreeAsync(
|
||||||
|
'git commit;git reset --soft HEAD~1;git reset --hard HEAD~1;gc;go C1;git reset --hard C3;',
|
||||||
|
'{"branches":{"master":{"target":"C3","id":"master"}},"commits":{"C0":{"parents":[],"id":"C0","rootCommit":true},"C1":{"parents":["C0"],"id":"C1"},"C2":{"parents":["C1"],"id":"C2"},"C3":{"parents":["C1"],"id":"C3"}},"HEAD":{"target":"C1","id":"HEAD"}}'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('Checkouts', function() {
|
it('Checkouts', function() {
|
||||||
expectTreeAsync(
|
expectTreeAsync(
|
||||||
'git checkout -b side',
|
'git checkout -b side',
|
||||||
|
@ -115,7 +137,7 @@ describe('GitEngine', function() {
|
||||||
|
|
||||||
it('Cherry picks', function() {
|
it('Cherry picks', function() {
|
||||||
expectTreeAsync(
|
expectTreeAsync(
|
||||||
'git checkout -b side C0; gc; git cherry-pick C1',
|
'git checkout -b side C0; gc; git cherry-pick C11; git cherry-pick C1',
|
||||||
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22side%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%22C0%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
'%7B%22branches%22%3A%7B%22master%22%3A%7B%22target%22%3A%22C1%22%2C%22id%22%3A%22master%22%7D%2C%22side%22%3A%7B%22target%22%3A%22C1%27%22%2C%22id%22%3A%22side%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%22C0%22%5D%2C%22id%22%3A%22C2%22%7D%2C%22C1%27%22%3A%7B%22parents%22%3A%5B%22C2%22%5D%2C%22id%22%3A%22C1%27%22%7D%7D%2C%22HEAD%22%3A%7B%22target%22%3A%22side%22%2C%22id%22%3A%22HEAD%22%7D%7D'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,14 +19,15 @@ var expectTreeAsync = function(headless, levelBlob) {
|
||||||
// dont do interactive rebase levels
|
// dont do interactive rebase levels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var start = Date.now();
|
|
||||||
|
|
||||||
|
var start;
|
||||||
runs(function() {
|
runs(function() {
|
||||||
|
start = Date.now();
|
||||||
headless.sendCommand(command);
|
headless.sendCommand(command);
|
||||||
});
|
});
|
||||||
waitsFor(function() {
|
waitsFor(function() {
|
||||||
var diff = (Date.now() - start);
|
var diff = (Date.now() - start);
|
||||||
if (diff > TIME - 50) {
|
if (diff > TIME - 10) {
|
||||||
console.log('not going to match', command);
|
console.log('not going to match', command);
|
||||||
}
|
}
|
||||||
var result = compareLevelTree(headless, levelBlob);
|
var result = compareLevelTree(headless, levelBlob);
|
||||||
|
|
|
@ -37,7 +37,9 @@ var Commands = {
|
||||||
msg = args[0];
|
msg = args[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
var newCommit = engine.commit();
|
var newCommit = engine.commit({
|
||||||
|
isAmend: commandOptions['--amend']
|
||||||
|
});
|
||||||
if (msg) {
|
if (msg) {
|
||||||
msg = msg
|
msg = msg
|
||||||
.replace(/"/g, '"')
|
.replace(/"/g, '"')
|
||||||
|
@ -54,6 +56,239 @@ var Commands = {
|
||||||
engine.animationQueue.thenFinish(promise);
|
engine.animationQueue.thenFinish(promise);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
cherrypick: function(engine, command) {
|
||||||
|
var commandOptions = command.getSupportedMap();
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
|
||||||
|
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE);
|
||||||
|
|
||||||
|
var set = engine.getUpstreamSet('HEAD');
|
||||||
|
// first resolve all the refs (as an error check)
|
||||||
|
var toCherrypick = _.map(generalArgs, function(arg) {
|
||||||
|
var commit = engine.getCommitFromRef(arg);
|
||||||
|
// and check that its not upstream
|
||||||
|
if (set[commit.get('id')]) {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str(
|
||||||
|
'git-error-already-exists',
|
||||||
|
{ commit: commit.get('id') }
|
||||||
|
)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return commit;
|
||||||
|
}, this);
|
||||||
|
|
||||||
|
engine.setupCherrypickChain(toCherrypick);
|
||||||
|
},
|
||||||
|
|
||||||
|
pull: function(engine, command) {
|
||||||
|
if (!engine.hasOrigin()) {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-origin-required')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var commandOptions = command.getSupportedMap();
|
||||||
|
command.acceptNoGeneralArgs();
|
||||||
|
engine.pull({
|
||||||
|
isRebase: commandOptions['--rebase']
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
fakeTeamwork: function(engine, command) {
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
if (!engine.hasOrigin()) {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-origin-required')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
command.validateArgBounds(generalArgs, 0, 2);
|
||||||
|
// allow formats of: git Faketeamwork 2 or git Faketeamwork side 3
|
||||||
|
var branch = (engine.origin.refs[generalArgs[0]]) ?
|
||||||
|
generalArgs[0] : 'master';
|
||||||
|
var numToMake = parseInt(generalArgs[0], 10) || generalArgs[1] || 1;
|
||||||
|
|
||||||
|
// make sure its a branch and exists
|
||||||
|
var destBranch = engine.origin.resolveID(branch);
|
||||||
|
if (destBranch.get('type') !== 'branch') {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-options')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.fakeTeamwork(numToMake, branch);
|
||||||
|
},
|
||||||
|
|
||||||
|
clone: function(engine, command) {
|
||||||
|
command.acceptNoGeneralArgs();
|
||||||
|
engine.makeOrigin(engine.printTree());
|
||||||
|
},
|
||||||
|
|
||||||
|
fetch: function(engine, command) {
|
||||||
|
if (!engine.hasOrigin()) {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-origin-required')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
command.acceptNoGeneralArgs();
|
||||||
|
engine.fetch();
|
||||||
|
},
|
||||||
|
|
||||||
|
branch: function(engine, command) {
|
||||||
|
var commandOptions = command.getSupportedMap();
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
|
||||||
|
var args = null;
|
||||||
|
// handle deletion first
|
||||||
|
if (commandOptions['-d'] || commandOptions['-D']) {
|
||||||
|
var names = commandOptions['-d'] || commandOptions['-D'];
|
||||||
|
command.validateArgBounds(names, 1, Number.MAX_VALUE, '-d');
|
||||||
|
|
||||||
|
_.each(names, function(name) {
|
||||||
|
engine.deleteBranch(name);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandOptions['--contains']) {
|
||||||
|
args = commandOptions['--contains'];
|
||||||
|
command.validateArgBounds(args, 1, 1, '--contains');
|
||||||
|
engine.printBranchesWithout(args[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandOptions['-f']) {
|
||||||
|
args = commandOptions['-f'];
|
||||||
|
command.twoArgsImpliedHead(args, '-f');
|
||||||
|
|
||||||
|
// we want to force a branch somewhere
|
||||||
|
engine.forceBranch(args[0], args[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (generalArgs.length === 0) {
|
||||||
|
var branches;
|
||||||
|
if (commandOptions['-a']) {
|
||||||
|
branches = engine.getBranches();
|
||||||
|
} else if (commandOptions['-r']) {
|
||||||
|
branches = engine.getRemoteBranches();
|
||||||
|
} else {
|
||||||
|
branches = engine.getLocalBranches();
|
||||||
|
}
|
||||||
|
engine.printBranches(branches);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
command.twoArgsImpliedHead(generalArgs);
|
||||||
|
engine.branch(generalArgs[0], generalArgs[1]);
|
||||||
|
},
|
||||||
|
|
||||||
|
add: function() {
|
||||||
|
throw new CommandResult({
|
||||||
|
msg: intl.str('git-error-staging')
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function(engine, command) {
|
||||||
|
var commandOptions = command.getSupportedMap();
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
|
||||||
|
if (commandOptions['--soft']) {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-staging')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (commandOptions['--hard']) {
|
||||||
|
command.addWarning(
|
||||||
|
intl.str('git-warning-hard')
|
||||||
|
);
|
||||||
|
// dont absorb the arg off of --hard
|
||||||
|
generalArgs = generalArgs.concat(commandOptions['--hard']);
|
||||||
|
}
|
||||||
|
|
||||||
|
command.validateArgBounds(generalArgs, 1, 1);
|
||||||
|
|
||||||
|
if (engine.getDetachedHead()) {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-reset-detached')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.reset(generalArgs[0]);
|
||||||
|
},
|
||||||
|
|
||||||
|
revert: function(engine, command) {
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
|
||||||
|
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE);
|
||||||
|
engine.revert(generalArgs);
|
||||||
|
},
|
||||||
|
|
||||||
|
merge: function(engine, command) {
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
command.validateArgBounds(generalArgs, 1, 1);
|
||||||
|
|
||||||
|
var newCommit = engine.merge(generalArgs[0]);
|
||||||
|
|
||||||
|
if (newCommit === undefined) {
|
||||||
|
// its just a fast forwrard
|
||||||
|
engine.animationFactory.refreshTree(
|
||||||
|
engine.animationQueue, engine.gitVisuals
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.animationFactory.genCommitBirthAnimation(
|
||||||
|
engine.animationQueue, newCommit, engine.gitVisuals
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
log: function(engine, command) {
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
|
||||||
|
if (generalArgs.length == 2) {
|
||||||
|
// do fancy git log branchA ^branchB
|
||||||
|
if (generalArgs[1][0] == '^') {
|
||||||
|
engine.logWithout(generalArgs[0], generalArgs[1]);
|
||||||
|
} else {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-options')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
command.oneArgImpliedHead(generalArgs);
|
||||||
|
engine.log(generalArgs[0]);
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function(engine, command) {
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
command.oneArgImpliedHead(generalArgs);
|
||||||
|
engine.show(generalArgs[0]);
|
||||||
|
},
|
||||||
|
|
||||||
|
rebase: function(engine, command) {
|
||||||
|
var commandOptions = command.getSupportedMap();
|
||||||
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
|
||||||
|
if (commandOptions['-i']) {
|
||||||
|
var args = commandOptions['-i'];
|
||||||
|
command.twoArgsImpliedHead(args, ' -i');
|
||||||
|
engine.rebaseInteractive(args[0], args[1]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
command.twoArgsImpliedHead(generalArgs);
|
||||||
|
engine.rebase(generalArgs[0], generalArgs[1]);
|
||||||
|
},
|
||||||
|
|
||||||
|
status: function(engine) {
|
||||||
|
// no parsing at all
|
||||||
|
engine.status();
|
||||||
|
},
|
||||||
|
|
||||||
checkout: function(engine, command) {
|
checkout: function(engine, command) {
|
||||||
var commandOptions = command.getSupportedMap();
|
var commandOptions = command.getSupportedMap();
|
||||||
var generalArgs = command.getGeneralArgs();
|
var generalArgs = command.getGeneralArgs();
|
||||||
|
@ -102,6 +337,16 @@ var Commands = {
|
||||||
engine.checkout(engine.crappyUnescape(generalArgs[0]));
|
engine.checkout(engine.crappyUnescape(generalArgs[0]));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
push: function(engine, command) {
|
||||||
|
if (!engine.hasOrigin()) {
|
||||||
|
throw new GitError({
|
||||||
|
msg: intl.str('git-error-origin-required')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
command.acceptNoGeneralArgs();
|
||||||
|
engine.push();
|
||||||
|
},
|
||||||
|
|
||||||
noComma: 123
|
noComma: 123
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -35,11 +35,6 @@ function GitEngine(options) {
|
||||||
this.animationFactory = (options.animationFactory) ?
|
this.animationFactory = (options.animationFactory) ?
|
||||||
options.animationFactory : AnimationFactory;
|
options.animationFactory : AnimationFactory;
|
||||||
|
|
||||||
// global variable to keep track of the options given
|
|
||||||
// along with the command call.
|
|
||||||
this.commandOptions = {};
|
|
||||||
this.generalArgs = [];
|
|
||||||
|
|
||||||
this.initUniqueID();
|
this.initUniqueID();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,68 +541,6 @@ GitEngine.prototype.makeCommit = function(parents, id, options) {
|
||||||
return commit;
|
return commit;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.acceptNoGeneralArgs = function() {
|
|
||||||
if (this.generalArgs.length) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-no-general-args')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.validateArgBounds = function(args, lower, upper, option) {
|
|
||||||
// this is a little utility class to help arg validation that happens over and over again
|
|
||||||
var what = (option === undefined) ?
|
|
||||||
'git ' + this.command.get('method') :
|
|
||||||
this.command.get('method') + ' ' + option + ' ';
|
|
||||||
what = 'with ' + what;
|
|
||||||
|
|
||||||
if (args.length < lower) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str(
|
|
||||||
'git-error-args-few',
|
|
||||||
{
|
|
||||||
lower: String(lower),
|
|
||||||
what: what
|
|
||||||
}
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (args.length > upper) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str(
|
|
||||||
'git-error-args-many',
|
|
||||||
{
|
|
||||||
upper: String(upper),
|
|
||||||
what: what
|
|
||||||
}
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.oneArgImpliedHead = function(args, option) {
|
|
||||||
// for log, show, etc
|
|
||||||
this.validateArgBounds(args, 0, 1, option);
|
|
||||||
if (args.length === 0) {
|
|
||||||
args.push('HEAD');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.twoArgsImpliedHead = function(args, option) {
|
|
||||||
// our args we expect to be between 1 and 2
|
|
||||||
this.validateArgBounds(args, 1, 2, option);
|
|
||||||
// and if it's one, add a HEAD to the back
|
|
||||||
if (args.length == 1) {
|
|
||||||
args.push('HEAD');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.revertStarter = function() {
|
|
||||||
this.validateArgBounds(this.generalArgs, 1, NaN);
|
|
||||||
|
|
||||||
this.revert(this.generalArgs);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.revert = function(whichCommits) {
|
GitEngine.prototype.revert = function(whichCommits) {
|
||||||
// resolve the commits we will rebase
|
// resolve the commits we will rebase
|
||||||
var toRevert = _.map(whichCommits, function(stringRef) {
|
var toRevert = _.map(whichCommits, function(stringRef) {
|
||||||
|
@ -659,54 +592,11 @@ GitEngine.prototype.revert = function(whichCommits) {
|
||||||
this.animationQueue.thenFinish(chain, deferred);
|
this.animationQueue.thenFinish(chain, deferred);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.resetStarter = function() {
|
|
||||||
if (this.commandOptions['--soft']) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-staging')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (this.commandOptions['--hard']) {
|
|
||||||
this.command.addWarning(
|
|
||||||
intl.str('git-warning-hard')
|
|
||||||
);
|
|
||||||
// dont absorb the arg off of --hard
|
|
||||||
this.generalArgs = this.generalArgs.concat(this.commandOptions['--hard']);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.validateArgBounds(this.generalArgs, 1, 1);
|
|
||||||
|
|
||||||
if (this.getDetachedHead()) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-reset-detached')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.reset(this.generalArgs[0]);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.reset = function(target) {
|
GitEngine.prototype.reset = function(target) {
|
||||||
this.setTargetLocation('HEAD', this.getCommitFromRef(target));
|
this.setTargetLocation('HEAD', this.getCommitFromRef(target));
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.cherrypickStarter = function() {
|
GitEngine.prototype.setupCherrypickChain = function(toCherrypick) {
|
||||||
this.validateArgBounds(this.generalArgs, 1, Number.MAX_VALUE);
|
|
||||||
|
|
||||||
var set = this.getUpstreamSet('HEAD');
|
|
||||||
// first resolve all the refs (as an error check)
|
|
||||||
var toCherrypick = _.map(this.generalArgs, function(arg) {
|
|
||||||
var commit = this.getCommitFromRef(arg);
|
|
||||||
// and check that its not upstream
|
|
||||||
if (set[commit.get('id')]) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str(
|
|
||||||
'git-error-already-exists',
|
|
||||||
{ commit: commit.get('id') }
|
|
||||||
)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return commit;
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
// error checks are all good, lets go!
|
// error checks are all good, lets go!
|
||||||
var deferred = Q.defer();
|
var deferred = Q.defer();
|
||||||
var chain = deferred.promise;
|
var chain = deferred.promise;
|
||||||
|
@ -827,16 +717,6 @@ GitEngine.prototype.getTargetGraphDifference = function(
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.pushStarter = function(options) {
|
|
||||||
if (!this.hasOrigin()) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-origin-required')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.acceptNoGeneralArgs();
|
|
||||||
this.push();
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.push = function(options) {
|
GitEngine.prototype.push = function(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var localBranch = this.refs['master'];
|
var localBranch = this.refs['master'];
|
||||||
|
@ -926,16 +806,6 @@ GitEngine.prototype.push = function(options) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.fetchStarter = function() {
|
|
||||||
if (!this.hasOrigin()) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-origin-required')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.acceptNoGeneralArgs();
|
|
||||||
this.fetch();
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.fetch = function(options) {
|
GitEngine.prototype.fetch = function(options) {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var localBranch = this.refs['o/master'];
|
var localBranch = this.refs['o/master'];
|
||||||
|
@ -1026,18 +896,8 @@ GitEngine.prototype.fetch = function(options) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.pullStarter = function() {
|
GitEngine.prototype.pull = function(options) {
|
||||||
if (!this.hasOrigin()) {
|
options = options || {};
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-origin-required')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.acceptNoGeneralArgs();
|
|
||||||
// eventually args go here
|
|
||||||
this.pull();
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.pull = function() {
|
|
||||||
var localBranch = this.refs['master'];
|
var localBranch = this.refs['master'];
|
||||||
var remoteBranch = this.refs['o/master'];
|
var remoteBranch = this.refs['o/master'];
|
||||||
|
|
||||||
|
@ -1047,7 +907,7 @@ GitEngine.prototype.pull = function() {
|
||||||
dontThrowOnNoFetch: true
|
dontThrowOnNoFetch: true
|
||||||
});
|
});
|
||||||
// then either rebase or merge
|
// then either rebase or merge
|
||||||
if (this.commandOptions['--rebase']) {
|
if (options.isRebase) {
|
||||||
this.pullFinishWithRebase(pendingFetch, localBranch, remoteBranch);
|
this.pullFinishWithRebase(pendingFetch, localBranch, remoteBranch);
|
||||||
} else {
|
} else {
|
||||||
this.pullFinishWithMerge(pendingFetch, localBranch, remoteBranch);
|
this.pullFinishWithMerge(pendingFetch, localBranch, remoteBranch);
|
||||||
|
@ -1136,35 +996,6 @@ GitEngine.prototype.pullFinishWithMerge = function(
|
||||||
this.animationQueue.thenFinish(chain, deferred);
|
this.animationQueue.thenFinish(chain, deferred);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.cloneStarter = function() {
|
|
||||||
this.acceptNoGeneralArgs();
|
|
||||||
this.makeOrigin(this.printTree());
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.fakeTeamworkStarter = function() {
|
|
||||||
if (!this.hasOrigin()) {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-origin-required')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.validateArgBounds(this.generalArgs, 0, 2);
|
|
||||||
// allow formats of: git Faketeamwork 2 or git Faketeamwork side 3
|
|
||||||
var branch = (this.origin.refs[this.generalArgs[0]]) ?
|
|
||||||
this.generalArgs[0] : 'master';
|
|
||||||
var numToMake = parseInt(this.generalArgs[0], 10) || this.generalArgs[1] || 1;
|
|
||||||
|
|
||||||
// make sure its a branch and exists
|
|
||||||
var destBranch = this.origin.resolveID(branch);
|
|
||||||
if (destBranch.get('type') !== 'branch') {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-options')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.fakeTeamwork(numToMake, branch);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.fakeTeamwork = function(numToMake, branch) {
|
GitEngine.prototype.fakeTeamwork = function(numToMake, branch) {
|
||||||
var makeOriginCommit = _.bind(function() {
|
var makeOriginCommit = _.bind(function() {
|
||||||
var id = this.getUniqueID();
|
var id = this.getUniqueID();
|
||||||
|
@ -1209,12 +1040,13 @@ GitEngine.prototype.cherrypick = function(commit) {
|
||||||
return newCommit;
|
return newCommit;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.commit = function() {
|
GitEngine.prototype.commit = function(options) {
|
||||||
|
options = options || {};
|
||||||
var targetCommit = this.getCommitFromRef(this.HEAD);
|
var targetCommit = this.getCommitFromRef(this.HEAD);
|
||||||
var id = null;
|
var id = null;
|
||||||
|
|
||||||
// if we want to ammend, go one above
|
// if we want to ammend, go one above
|
||||||
if (this.commandOptions['--amend']) {
|
if (options.isAmend) {
|
||||||
targetCommit = this.resolveID('HEAD~1');
|
targetCommit = this.resolveID('HEAD~1');
|
||||||
id = this.rebaseAltID(this.getCommitFromRef('HEAD').get('id'));
|
id = this.rebaseAltID(this.getCommitFromRef('HEAD').get('id'));
|
||||||
}
|
}
|
||||||
|
@ -1511,23 +1343,6 @@ GitEngine.prototype.dateSortFunc = function(cA, cB) {
|
||||||
return dateA - dateB;
|
return dateA - dateB;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.rebaseInteractiveStarter = function() {
|
|
||||||
var args = this.commandOptions['-i'];
|
|
||||||
this.twoArgsImpliedHead(args, ' -i');
|
|
||||||
|
|
||||||
this.rebaseInteractive(args[0], args[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.rebaseStarter = function() {
|
|
||||||
if (this.commandOptions['-i']) {
|
|
||||||
this.rebaseInteractiveStarter();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.twoArgsImpliedHead(this.generalArgs);
|
|
||||||
this.rebase(this.generalArgs[0], this.generalArgs[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.rebase = function(targetSource, currentLocation, options) {
|
GitEngine.prototype.rebase = function(targetSource, currentLocation, options) {
|
||||||
// first some conditions
|
// first some conditions
|
||||||
if (this.isUpstreamOf(targetSource, currentLocation)) {
|
if (this.isUpstreamOf(targetSource, currentLocation)) {
|
||||||
|
@ -1755,20 +1570,6 @@ GitEngine.prototype.rebaseFinish = function(
|
||||||
return chain;
|
return chain;
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.mergeStarter = function() {
|
|
||||||
this.validateArgBounds(this.generalArgs, 1, 1);
|
|
||||||
|
|
||||||
var newCommit = this.merge(this.generalArgs[0]);
|
|
||||||
|
|
||||||
if (newCommit === undefined) {
|
|
||||||
// its just a fast forwrard
|
|
||||||
this.animationFactory.refreshTree(this.animationQueue, this.gitVisuals);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.animationFactory.genCommitBirthAnimation(this.animationQueue, newCommit, this.gitVisuals);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.merge = function(targetSource) {
|
GitEngine.prototype.merge = function(targetSource) {
|
||||||
var currentLocation = 'HEAD';
|
var currentLocation = 'HEAD';
|
||||||
|
|
||||||
|
@ -1837,53 +1638,6 @@ GitEngine.prototype.checkout = function(idOrTarget) {
|
||||||
this.HEAD.set('target', target);
|
this.HEAD.set('target', target);
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.branchStarter = function() {
|
|
||||||
var args = null;
|
|
||||||
// handle deletion first
|
|
||||||
if (this.commandOptions['-d'] || this.commandOptions['-D']) {
|
|
||||||
var names = this.commandOptions['-d'] || this.commandOptions['-D'];
|
|
||||||
this.validateArgBounds(names, 1, NaN, '-d');
|
|
||||||
|
|
||||||
_.each(names, function(name) {
|
|
||||||
this.deleteBranch(name);
|
|
||||||
}, this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.commandOptions['--contains']) {
|
|
||||||
args = this.commandOptions['--contains'];
|
|
||||||
this.validateArgBounds(args, 1, 1, '--contains');
|
|
||||||
this.printBranchesWithout(args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.commandOptions['-f']) {
|
|
||||||
args = this.commandOptions['-f'];
|
|
||||||
this.twoArgsImpliedHead(args, '-f');
|
|
||||||
|
|
||||||
// we want to force a branch somewhere
|
|
||||||
this.forceBranch(args[0], args[1]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (this.generalArgs.length === 0) {
|
|
||||||
var branches;
|
|
||||||
if (this.commandOptions['-a']) {
|
|
||||||
branches = this.getBranches();
|
|
||||||
} else if (this.commandOptions['-r']) {
|
|
||||||
branches = this.getRemoteBranches();
|
|
||||||
} else {
|
|
||||||
branches = this.getLocalBranches();
|
|
||||||
}
|
|
||||||
this.printBranches(branches);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.twoArgsImpliedHead(this.generalArgs);
|
|
||||||
this.branch(this.generalArgs[0], this.generalArgs[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.forceBranch = function(branchName, where) {
|
GitEngine.prototype.forceBranch = function(branchName, where) {
|
||||||
branchName = this.crappyUnescape(branchName);
|
branchName = this.crappyUnescape(branchName);
|
||||||
// if branchname doesn't exist...
|
// if branchname doesn't exist...
|
||||||
|
@ -1966,11 +1720,7 @@ GitEngine.prototype.externalRefresh = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.dispatch = function(command, deferred) {
|
GitEngine.prototype.dispatch = function(command, deferred) {
|
||||||
// current command, options, and args are stored in the gitEngine
|
|
||||||
// for easy reference during processing.
|
|
||||||
this.command = command;
|
this.command = command;
|
||||||
this.commandOptions = command.get('supportedMap');
|
|
||||||
this.generalArgs = command.get('generalArgs');
|
|
||||||
|
|
||||||
// set up the animation queue
|
// set up the animation queue
|
||||||
var whenDone = _.bind(function() {
|
var whenDone = _.bind(function() {
|
||||||
|
@ -1982,13 +1732,7 @@ GitEngine.prototype.dispatch = function(command, deferred) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var methodName = command.get('method').replace(/-/g, '');
|
var methodName = command.get('method').replace(/-/g, '');
|
||||||
// first check out module
|
|
||||||
if (Commands[methodName]) {
|
|
||||||
Commands[methodName](this, this.command);
|
Commands[methodName](this, this.command);
|
||||||
} else {
|
|
||||||
var startName = methodName + 'Starter';
|
|
||||||
this[startName]();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.filterError(err);
|
this.filterError(err);
|
||||||
// short circuit animation by just setting error and returning
|
// short circuit animation by just setting error and returning
|
||||||
|
@ -2011,12 +1755,6 @@ GitEngine.prototype.dispatch = function(command, deferred) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.showStarter = function() {
|
|
||||||
this.oneArgImpliedHead(this.generalArgs);
|
|
||||||
|
|
||||||
this.show(this.generalArgs[0]);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.show = function(ref) {
|
GitEngine.prototype.show = function(ref) {
|
||||||
var commit = this.getCommitFromRef(ref);
|
var commit = this.getCommitFromRef(ref);
|
||||||
|
|
||||||
|
@ -2025,7 +1763,8 @@ GitEngine.prototype.show = function(ref) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.statusStarter = function() {
|
GitEngine.prototype.status = function() {
|
||||||
|
// UGLY todo
|
||||||
var lines = [];
|
var lines = [];
|
||||||
if (this.getDetachedHead()) {
|
if (this.getDetachedHead()) {
|
||||||
lines.push(intl.str('git-status-detached'));
|
lines.push(intl.str('git-status-detached'));
|
||||||
|
@ -2049,22 +1788,6 @@ GitEngine.prototype.statusStarter = function() {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.logStarter = function() {
|
|
||||||
if (this.generalArgs.length == 2) {
|
|
||||||
// do fancy git log branchA ^branchB
|
|
||||||
if (this.generalArgs[1][0] == '^') {
|
|
||||||
this.logWithout(this.generalArgs[0], this.generalArgs[1]);
|
|
||||||
} else {
|
|
||||||
throw new GitError({
|
|
||||||
msg: intl.str('git-error-options')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.oneArgImpliedHead(this.generalArgs);
|
|
||||||
this.log(this.generalArgs[0]);
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.logWithout = function(ref, omitBranch) {
|
GitEngine.prototype.logWithout = function(ref, omitBranch) {
|
||||||
// slice off the ^branch
|
// slice off the ^branch
|
||||||
omitBranch = omitBranch.slice(1);
|
omitBranch = omitBranch.slice(1);
|
||||||
|
@ -2108,12 +1831,6 @@ GitEngine.prototype.log = function(ref, omitSet) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
GitEngine.prototype.addStarter = function() {
|
|
||||||
throw new CommandResult({
|
|
||||||
msg: intl.str('git-error-staging')
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
GitEngine.prototype.getCommonAncestor = function(ancestor, cousin) {
|
GitEngine.prototype.getCommonAncestor = function(ancestor, cousin) {
|
||||||
if (this.isUpstreamOf(cousin, ancestor)) {
|
if (this.isUpstreamOf(cousin, ancestor)) {
|
||||||
throw new Error('Dont use common ancestor if we are upstream!');
|
throw new Error('Dont use common ancestor if we are upstream!');
|
||||||
|
|
|
@ -69,6 +69,14 @@ var Command = Backbone.Model.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
oneArgImpliedHead: function(args, option) {
|
||||||
|
this.validateArgBounds(args, 0, 1, option);
|
||||||
|
// and if it's one, add a HEAD to the back
|
||||||
|
if (args.length === 0) {
|
||||||
|
args.push('HEAD');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
twoArgsImpliedHead: function(args, option) {
|
twoArgsImpliedHead: function(args, option) {
|
||||||
// our args we expect to be between 1 and 2
|
// our args we expect to be between 1 and 2
|
||||||
this.validateArgBounds(args, 1, 2, option);
|
this.validateArgBounds(args, 1, 2, option);
|
||||||
|
|
13
todo.txt
13
todo.txt
|
@ -2,17 +2,9 @@ Mega Things
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
[-] origin support
|
[-] origin support
|
||||||
|
|
||||||
Before everything else:
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Intl TODO
|
|
||||||
~~~~~~~~~~~~~~~~~~~
|
|
||||||
[ ] translation script? might be too late...
|
|
||||||
|
|
||||||
Big Things
|
Big Things
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
[ ] compare settings for a level!!! integrated into builder...
|
[ ] compare settings for a level!!! integrated into builder...
|
||||||
[ ] get goal visualization to show origin / remote.... hrm :O
|
|
||||||
[ ] tree pruning
|
[ ] tree pruning
|
||||||
|
|
||||||
Easier origin things:
|
Easier origin things:
|
||||||
|
@ -30,6 +22,7 @@ Origin things:
|
||||||
|
|
||||||
Medium things:
|
Medium things:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
[ ] factor regexes and instant commands into one module
|
||||||
|
|
||||||
Cases to handle / things to edit
|
Cases to handle / things to edit
|
||||||
=======================
|
=======================
|
||||||
|
@ -49,6 +42,10 @@ 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] get demonstration view to show origin / remote -- z index ugliness
|
||||||
|
[x] get goal visualization to show origin / remote.... hrm :O
|
||||||
|
[x] MASSIVE EFFIN REFACTOR of all command options outside of git engine and into separate module
|
||||||
|
[x] facebook page link :D
|
||||||
[x] tree comparison with origin.... done! not too bad
|
[x] tree comparison with origin.... done! not too bad
|
||||||
[x] green refactor tree compare to have map
|
[x] green refactor tree compare to have map
|
||||||
[x] increase test coverage over everything
|
[x] increase test coverage over everything
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue