|
|
var escapeString = require('../util/escapeString'); |
|
|
var intl = require('../intl'); |
|
|
|
|
|
var Graph = require('../graph'); |
|
|
var Errors = require('../util/errors'); |
|
|
var CommandProcessError = Errors.CommandProcessError; |
|
|
var GitError = Errors.GitError; |
|
|
var Warning = Errors.Warning; |
|
|
var CommandResult = Errors.CommandResult; |
|
|
|
|
|
var ORIGIN_PREFIX = 'o/'; |
|
|
|
|
|
var crappyUnescape = function(str) { |
|
|
return str.replace(/'/g, "'").replace(///g, "/"); |
|
|
}; |
|
|
|
|
|
function isColonRefspec(str) { |
|
|
return str.indexOf(':') !== -1 && str.split(':').length === 2; |
|
|
} |
|
|
|
|
|
var assertIsRef = function(engine, ref) { |
|
|
engine.resolveID(ref); |
|
|
}; |
|
|
|
|
|
var validateBranchName = function(engine, name) { |
|
|
return engine.validateBranchName(name); |
|
|
}; |
|
|
|
|
|
var validateOriginBranchName = function(engine, name) { |
|
|
return engine.origin.validateBranchName(name); |
|
|
}; |
|
|
|
|
|
var validateBranchNameIfNeeded = function(engine, name) { |
|
|
if (engine.refs[name]) { |
|
|
return name; |
|
|
} |
|
|
return validateBranchName(engine, name); |
|
|
}; |
|
|
|
|
|
var assertNotCheckedOut = function(engine, ref) { |
|
|
if (!engine.refs[ref]) { |
|
|
return; |
|
|
} |
|
|
if (engine.HEAD.get('target') === engine.refs[ref]) { |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
'cannot fetch to ' + ref + ' when checked out on ' + ref |
|
|
) |
|
|
}); |
|
|
} |
|
|
}; |
|
|
|
|
|
var assertIsBranch = function(engine, ref) { |
|
|
assertIsRef(engine, ref); |
|
|
var obj = engine.resolveID(ref); |
|
|
if (!obj || obj.get('type') !== 'branch') { |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
ref + ' is not a branch' |
|
|
) |
|
|
}); |
|
|
} |
|
|
}; |
|
|
|
|
|
var assertIsRemoteBranch = function(engine, ref) { |
|
|
assertIsRef(engine, ref); |
|
|
var obj = engine.resolveID(ref); |
|
|
|
|
|
if (obj.get('type') !== 'branch' || |
|
|
!obj.getIsRemote()) { |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
ref + ' is not a remote branch' |
|
|
) |
|
|
}); |
|
|
} |
|
|
}; |
|
|
|
|
|
var assertOriginSpecified = function(generalArgs) { |
|
|
if (!generalArgs.length) { |
|
|
return; |
|
|
} |
|
|
if (generalArgs[0] !== 'origin') { |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
generalArgs[0] + ' is not a remote in your repository! try adding origin to that argument' |
|
|
) |
|
|
}); |
|
|
} |
|
|
}; |
|
|
|
|
|
var assertBranchIsRemoteTracking = function(engine, branchName) { |
|
|
branchName = crappyUnescape(branchName); |
|
|
if (!engine.resolveID(branchName)) { |
|
|
throw new GitError({ |
|
|
msg: intl.todo(branchName + ' is not a branch!') |
|
|
}); |
|
|
} |
|
|
var branch = engine.resolveID(branchName); |
|
|
if (branch.get('type') !== 'branch') { |
|
|
throw new GitError({ |
|
|
msg: intl.todo(branchName + ' is not a branch!') |
|
|
}); |
|
|
} |
|
|
|
|
|
var tracking = branch.getRemoteTrackingBranchID(); |
|
|
if (!tracking) { |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
branchName + ' is not a remote tracking branch! I don\'t know where to push' |
|
|
) |
|
|
}); |
|
|
} |
|
|
return tracking; |
|
|
}; |
|
|
|
|
|
var commandConfig = { |
|
|
commit: { |
|
|
sc: /^(gc|git ci)($|\s)/, |
|
|
regex: /^git +commit($|\s)/, |
|
|
options: [ |
|
|
'--amend', |
|
|
'-a', |
|
|
'--all', |
|
|
'-am', |
|
|
'-m' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
command.acceptNoGeneralArgs(); |
|
|
|
|
|
if (commandOptions['-am'] && ( |
|
|
commandOptions['-a'] || commandOptions['--all'] || commandOptions['-m'])) { |
|
|
throw new GitError({ |
|
|
msg: intl.str('git-error-options') |
|
|
}); |
|
|
} |
|
|
|
|
|
var msg = null; |
|
|
var args = null; |
|
|
if (commandOptions['-a'] || commandOptions['--all']) { |
|
|
command.addWarning(intl.str('git-warning-add')); |
|
|
} |
|
|
|
|
|
if (commandOptions['-am']) { |
|
|
args = commandOptions['-am']; |
|
|
command.validateArgBounds(args, 1, 1, '-am'); |
|
|
msg = args[0]; |
|
|
} |
|
|
|
|
|
if (commandOptions['-m']) { |
|
|
args = commandOptions['-m']; |
|
|
command.validateArgBounds(args, 1, 1, '-m'); |
|
|
msg = args[0]; |
|
|
} |
|
|
|
|
|
if (commandOptions['--amend']) { |
|
|
args = commandOptions['--amend']; |
|
|
command.validateArgBounds(args, 0, 0, '--amend'); |
|
|
} |
|
|
|
|
|
var newCommit = engine.commit({ |
|
|
isAmend: !!commandOptions['--amend'] |
|
|
}); |
|
|
if (msg) { |
|
|
msg = msg |
|
|
.replace(/"/g, '"') |
|
|
.replace(/^"/g, '') |
|
|
.replace(/"$/g, ''); |
|
|
|
|
|
newCommit.set('commitMessage', msg); |
|
|
} |
|
|
|
|
|
var promise = engine.animationFactory.playCommitBirthPromiseAnimation( |
|
|
newCommit, |
|
|
engine.gitVisuals |
|
|
); |
|
|
engine.animationQueue.thenFinish(promise); |
|
|
} |
|
|
}, |
|
|
|
|
|
cherrypick: { |
|
|
displayName: 'cherry-pick', |
|
|
regex: /^git +cherry-pick($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
|
|
|
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE); |
|
|
|
|
|
var set = Graph.getUpstreamSet(engine, 'HEAD'); |
|
|
|
|
|
var toCherrypick = generalArgs.map(function (arg) { |
|
|
var commit = engine.getCommitFromRef(arg); |
|
|
|
|
|
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); |
|
|
} |
|
|
}, |
|
|
|
|
|
gc: { |
|
|
displayName: 'gc', |
|
|
regex: /^git +gc($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
engine.pruneTree(false); |
|
|
} |
|
|
}, |
|
|
|
|
|
pull: { |
|
|
regex: /^git +pull($|\s)/, |
|
|
options: [ |
|
|
'--rebase' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
if (!engine.hasOrigin()) { |
|
|
throw new GitError({ |
|
|
msg: intl.str('git-error-origin-required') |
|
|
}); |
|
|
} |
|
|
|
|
|
var commandOptions = command.getOptionsMap(); |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
command.twoArgsForOrigin(generalArgs); |
|
|
assertOriginSpecified(generalArgs); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var source; |
|
|
var destination; |
|
|
var firstArg = generalArgs[1]; |
|
|
|
|
|
if (firstArg && isColonRefspec(firstArg)) { |
|
|
var refspecParts = firstArg.split(':'); |
|
|
source = refspecParts[0]; |
|
|
destination = validateBranchNameIfNeeded( |
|
|
engine, |
|
|
crappyUnescape(refspecParts[1]) |
|
|
); |
|
|
assertNotCheckedOut(engine, destination); |
|
|
} else if (firstArg) { |
|
|
source = firstArg; |
|
|
assertIsBranch(engine.origin, source); |
|
|
|
|
|
destination = engine.origin.resolveID(source).getPrefixedID(); |
|
|
} else { |
|
|
|
|
|
if (engine.getDetachedHead()) { |
|
|
throw new GitError({ |
|
|
msg: intl.todo('Git pull can not be executed in detached HEAD mode if no remote branch specified!') |
|
|
}); |
|
|
} |
|
|
|
|
|
|
|
|
var branch = engine.getOneBeforeCommit('HEAD'); |
|
|
var branchName = branch.get('id'); |
|
|
assertBranchIsRemoteTracking(engine, branchName); |
|
|
destination = branch.getRemoteTrackingBranchID(); |
|
|
source = destination.replace(ORIGIN_PREFIX, ''); |
|
|
} |
|
|
|
|
|
engine.pull({ |
|
|
source: source, |
|
|
destination: destination, |
|
|
isRebase: !!commandOptions['--rebase'] |
|
|
}); |
|
|
} |
|
|
}, |
|
|
|
|
|
fakeTeamwork: { |
|
|
regex: /^git +fakeTeamwork($|\s)/, |
|
|
execute: 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); |
|
|
var branch; |
|
|
var numToMake; |
|
|
|
|
|
|
|
|
switch (generalArgs.length) { |
|
|
|
|
|
case 0: |
|
|
branch = 'main'; |
|
|
numToMake = 1; |
|
|
break; |
|
|
|
|
|
|
|
|
case 1: |
|
|
if (isNaN(parseInt(generalArgs[0], 10))) { |
|
|
branch = validateOriginBranchName(engine, generalArgs[0]); |
|
|
numToMake = 1; |
|
|
} else { |
|
|
numToMake = parseInt(generalArgs[0], 10); |
|
|
branch = 'main'; |
|
|
} |
|
|
break; |
|
|
|
|
|
case 2: |
|
|
branch = validateOriginBranchName(engine, generalArgs[0]); |
|
|
if (isNaN(parseInt(generalArgs[1], 10))) { |
|
|
throw new GitError({ |
|
|
msg: 'Bad numeric argument: ' + generalArgs[1] |
|
|
}); |
|
|
} |
|
|
numToMake = parseInt(generalArgs[1], 10); |
|
|
break; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
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: { |
|
|
regex: /^git +clone *?$/, |
|
|
execute: function(engine, command) { |
|
|
command.acceptNoGeneralArgs(); |
|
|
engine.makeOrigin(engine.printTree()); |
|
|
} |
|
|
}, |
|
|
|
|
|
remote: { |
|
|
regex: /^git +remote($|\s)/, |
|
|
options: [ |
|
|
'-v' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
command.acceptNoGeneralArgs(); |
|
|
if (!engine.hasOrigin()) { |
|
|
throw new CommandResult({ |
|
|
msg: '' |
|
|
}); |
|
|
} |
|
|
|
|
|
engine.printRemotes({ |
|
|
verbose: !!command.getOptionsMap()['-v'] |
|
|
}); |
|
|
} |
|
|
}, |
|
|
|
|
|
fetch: { |
|
|
regex: /^git +fetch($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
if (!engine.hasOrigin()) { |
|
|
throw new GitError({ |
|
|
msg: intl.str('git-error-origin-required') |
|
|
}); |
|
|
} |
|
|
|
|
|
var source; |
|
|
var destination; |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
command.twoArgsForOrigin(generalArgs); |
|
|
assertOriginSpecified(generalArgs); |
|
|
|
|
|
var firstArg = generalArgs[1]; |
|
|
if (firstArg && isColonRefspec(firstArg)) { |
|
|
var refspecParts = firstArg.split(':'); |
|
|
source = refspecParts[0]; |
|
|
destination = validateBranchNameIfNeeded( |
|
|
engine, |
|
|
crappyUnescape(refspecParts[1]) |
|
|
); |
|
|
assertNotCheckedOut(engine, destination); |
|
|
} else if (firstArg) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
source = firstArg; |
|
|
assertIsBranch(engine.origin, source); |
|
|
|
|
|
destination = engine.origin.resolveID(source).getPrefixedID(); |
|
|
} |
|
|
if (source) { |
|
|
assertIsRef(engine.origin, source); |
|
|
} |
|
|
|
|
|
engine.fetch({ |
|
|
source: source, |
|
|
destination: destination |
|
|
}); |
|
|
} |
|
|
}, |
|
|
|
|
|
branch: { |
|
|
sc: /^(gb|git br)($|\s)/, |
|
|
regex: /^git +branch($|\s)/, |
|
|
options: [ |
|
|
'-d', |
|
|
'-D', |
|
|
'-f', |
|
|
'--force', |
|
|
'-a', |
|
|
'-r', |
|
|
'-u', |
|
|
'--contains' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
|
|
|
var args = null; |
|
|
|
|
|
if (commandOptions['-d'] || commandOptions['-D']) { |
|
|
var names = commandOptions['-d'] || commandOptions['-D']; |
|
|
names = names.concat(generalArgs); |
|
|
command.validateArgBounds(names, 1, Number.MAX_VALUE, '-d'); |
|
|
|
|
|
names.forEach(function(name) { |
|
|
engine.validateAndDeleteBranch(name); |
|
|
}); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (commandOptions['-u']) { |
|
|
args = commandOptions['-u'].concat(generalArgs); |
|
|
command.validateArgBounds(args, 1, 2, '-u'); |
|
|
var remoteBranch = crappyUnescape(args[0]); |
|
|
var branch = args[1] || engine.getOneBeforeCommit('HEAD').get('id'); |
|
|
|
|
|
|
|
|
assertIsRemoteBranch(engine, remoteBranch); |
|
|
assertIsBranch(engine, branch); |
|
|
engine.setLocalToTrackRemote( |
|
|
engine.resolveID(branch), |
|
|
engine.resolveID(remoteBranch) |
|
|
); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (commandOptions['--contains']) { |
|
|
args = commandOptions['--contains']; |
|
|
command.validateArgBounds(args, 1, 1, '--contains'); |
|
|
engine.printBranchesWithout(args[0]); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (commandOptions['-f'] || commandOptions['--force']) { |
|
|
args = commandOptions['-f'] || commandOptions['--force']; |
|
|
args = args.concat(generalArgs); |
|
|
command.twoArgsImpliedHead(args, '-f'); |
|
|
|
|
|
|
|
|
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: { |
|
|
dontCountForGolf: true, |
|
|
sc: /^ga($|\s)/, |
|
|
regex: /^git +add($|\s)/, |
|
|
execute: function() { |
|
|
throw new CommandResult({ |
|
|
msg: intl.str('git-error-staging') |
|
|
}); |
|
|
} |
|
|
}, |
|
|
|
|
|
reset: { |
|
|
regex: /^git +reset($|\s)/, |
|
|
options: [ |
|
|
'--hard', |
|
|
'--soft' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
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') |
|
|
); |
|
|
|
|
|
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: { |
|
|
regex: /^git +revert($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
|
|
|
command.validateArgBounds(generalArgs, 1, Number.MAX_VALUE); |
|
|
engine.revert(generalArgs); |
|
|
} |
|
|
}, |
|
|
|
|
|
merge: { |
|
|
regex: /^git +merge($|\s)/, |
|
|
options: [ |
|
|
'--no-ff' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
var generalArgs = command.getGeneralArgs().concat(commandOptions['--no-ff'] || []); |
|
|
command.validateArgBounds(generalArgs, 1, 1); |
|
|
|
|
|
var newCommit = engine.merge( |
|
|
generalArgs[0], |
|
|
{ noFF: !!commandOptions['--no-ff'] } |
|
|
); |
|
|
|
|
|
if (newCommit === undefined) { |
|
|
|
|
|
engine.animationFactory.refreshTree( |
|
|
engine.animationQueue, engine.gitVisuals |
|
|
); |
|
|
return; |
|
|
} |
|
|
|
|
|
engine.animationFactory.genCommitBirthAnimation( |
|
|
engine.animationQueue, newCommit, engine.gitVisuals |
|
|
); |
|
|
} |
|
|
}, |
|
|
|
|
|
revlist: { |
|
|
dontCountForGolf: true, |
|
|
displayName: 'rev-list', |
|
|
regex: /^git +rev-list($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
command.validateArgBounds(generalArgs, 1); |
|
|
|
|
|
engine.revlist(generalArgs); |
|
|
} |
|
|
}, |
|
|
|
|
|
log: { |
|
|
dontCountForGolf: true, |
|
|
regex: /^git +log($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
|
|
|
command.impliedHead(generalArgs, 0); |
|
|
engine.log(generalArgs); |
|
|
} |
|
|
}, |
|
|
|
|
|
show: { |
|
|
dontCountForGolf: true, |
|
|
regex: /^git +show($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
command.oneArgImpliedHead(generalArgs); |
|
|
engine.show(generalArgs[0]); |
|
|
} |
|
|
}, |
|
|
|
|
|
rebase: { |
|
|
sc: /^gr($|\s)/, |
|
|
options: [ |
|
|
'-i', |
|
|
'--solution-ordering', |
|
|
'--interactive-test', |
|
|
'--aboveAll', |
|
|
'-p', |
|
|
'--preserve-merges', |
|
|
'--onto' |
|
|
], |
|
|
regex: /^git +rebase($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
|
|
|
if (commandOptions['-i']) { |
|
|
var args = commandOptions['-i'].concat(generalArgs); |
|
|
command.twoArgsImpliedHead(args, ' -i'); |
|
|
|
|
|
if (commandOptions['--interactive-test']) { |
|
|
engine.rebaseInteractiveTest( |
|
|
args[0], |
|
|
args[1], { |
|
|
interactiveTest: commandOptions['--interactive-test'] |
|
|
} |
|
|
); |
|
|
} else { |
|
|
engine.rebaseInteractive( |
|
|
args[0], |
|
|
args[1], { |
|
|
aboveAll: !!commandOptions['--aboveAll'], |
|
|
initialCommitOrdering: commandOptions['--solution-ordering'] |
|
|
} |
|
|
); |
|
|
} |
|
|
return; |
|
|
} |
|
|
|
|
|
if (commandOptions['--onto']) { |
|
|
var args = commandOptions['--onto'].concat(generalArgs); |
|
|
command.threeArgsImpliedHead(args, ' --onto'); |
|
|
|
|
|
engine.rebaseOnto(args[0], args[1], args[2], { |
|
|
preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'] |
|
|
}); |
|
|
|
|
|
return; |
|
|
} |
|
|
|
|
|
command.twoArgsImpliedHead(generalArgs); |
|
|
engine.rebase(generalArgs[0], generalArgs[1], { |
|
|
preserveMerges: commandOptions['-p'] || commandOptions['--preserve-merges'] |
|
|
}); |
|
|
} |
|
|
}, |
|
|
|
|
|
status: { |
|
|
dontCountForGolf: true, |
|
|
sc: /^(gst|gs|git st)($|\s)/, |
|
|
regex: /^git +status($|\s)/, |
|
|
execute: function(engine) { |
|
|
|
|
|
engine.status(); |
|
|
} |
|
|
}, |
|
|
|
|
|
checkout: { |
|
|
sc: /^(go|git co)($|\s)/, |
|
|
regex: /^git +checkout($|\s)/, |
|
|
options: [ |
|
|
'-b', |
|
|
'-B', |
|
|
'-' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
|
|
|
var args = null; |
|
|
if (commandOptions['-b']) { |
|
|
|
|
|
|
|
|
args = commandOptions['-b'].concat(generalArgs); |
|
|
command.twoArgsImpliedHead(args, '-b'); |
|
|
|
|
|
var validId = engine.validateBranchName(args[0]); |
|
|
engine.branch(validId, args[1]); |
|
|
engine.checkout(validId); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (commandOptions['-']) { |
|
|
|
|
|
var lastPlace = engine.HEAD.get('lastLastTarget'); |
|
|
if (!lastPlace) { |
|
|
throw new GitError({ |
|
|
msg: intl.str('git-result-nothing') |
|
|
}); |
|
|
} |
|
|
engine.HEAD.set('target', lastPlace); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (commandOptions['-B']) { |
|
|
args = commandOptions['-B'].concat(generalArgs); |
|
|
command.twoArgsImpliedHead(args, '-B'); |
|
|
|
|
|
engine.forceBranch(args[0], args[1]); |
|
|
engine.checkout(args[0]); |
|
|
return; |
|
|
} |
|
|
|
|
|
command.validateArgBounds(generalArgs, 1, 1); |
|
|
|
|
|
engine.checkout(engine.crappyUnescape(generalArgs[0])); |
|
|
} |
|
|
}, |
|
|
|
|
|
push: { |
|
|
regex: /^git +push($|\s)/, |
|
|
options: [ |
|
|
'--force' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
if (!engine.hasOrigin()) { |
|
|
throw new GitError({ |
|
|
msg: intl.str('git-error-origin-required') |
|
|
}); |
|
|
} |
|
|
|
|
|
var options = {}; |
|
|
var destination; |
|
|
var source; |
|
|
var sourceObj; |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
|
|
|
|
|
|
|
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
command.twoArgsForOrigin(generalArgs); |
|
|
assertOriginSpecified(generalArgs); |
|
|
|
|
|
var firstArg = generalArgs[1]; |
|
|
if (firstArg && isColonRefspec(firstArg)) { |
|
|
var refspecParts = firstArg.split(':'); |
|
|
source = refspecParts[0]; |
|
|
destination = validateBranchName(engine, refspecParts[1]); |
|
|
if (source === "" && !engine.origin.resolveID(destination)) { |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
'cannot delete branch ' + options.destination + ' which doesnt exist' |
|
|
) |
|
|
}); |
|
|
} |
|
|
} else { |
|
|
if (firstArg) { |
|
|
|
|
|
|
|
|
|
|
|
assertIsRef(engine, firstArg); |
|
|
sourceObj = engine.resolveID(firstArg); |
|
|
} else { |
|
|
|
|
|
|
|
|
sourceObj = engine.getOneBeforeCommit('HEAD'); |
|
|
} |
|
|
source = sourceObj.get('id'); |
|
|
|
|
|
|
|
|
|
|
|
if (sourceObj.getRemoteTrackingBranchID && |
|
|
sourceObj.getRemoteTrackingBranchID()) { |
|
|
assertBranchIsRemoteTracking(engine, source); |
|
|
var remoteBranch = sourceObj.getRemoteTrackingBranchID(); |
|
|
destination = engine.resolveID(remoteBranch).getBaseID(); |
|
|
} else { |
|
|
destination = validateBranchName(engine, source); |
|
|
} |
|
|
} |
|
|
if (source) { |
|
|
assertIsRef(engine, source); |
|
|
} |
|
|
|
|
|
engine.push({ |
|
|
|
|
|
|
|
|
destination: destination, |
|
|
source: source, |
|
|
force: !!commandOptions['--force'] |
|
|
}); |
|
|
} |
|
|
}, |
|
|
|
|
|
describe: { |
|
|
regex: /^git +describe($|\s)/, |
|
|
execute: function(engine, command) { |
|
|
|
|
|
if (engine.tagCollection.toArray().length === 0) { |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
'fatal: No tags found, cannot describe anything.' |
|
|
) |
|
|
}); |
|
|
} |
|
|
|
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
command.oneArgImpliedHead(generalArgs); |
|
|
assertIsRef(engine, generalArgs[0]); |
|
|
|
|
|
engine.describe(generalArgs[0]); |
|
|
} |
|
|
}, |
|
|
|
|
|
tag: { |
|
|
regex: /^git +tag($|\s)/, |
|
|
options: [ |
|
|
'-d' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
|
|
|
if (commandOptions['-d']) { |
|
|
var tagID = commandOptions['-d']; |
|
|
var tagToRemove; |
|
|
|
|
|
assertIsRef(engine, tagID); |
|
|
|
|
|
command.oneArgImpliedHead(tagID); |
|
|
engine.tagCollection.each(function(tag) { |
|
|
if(tag.get('id') == tagID){ |
|
|
tagToRemove = tag; |
|
|
} |
|
|
}, true); |
|
|
|
|
|
if(tagToRemove == undefined){ |
|
|
throw new GitError({ |
|
|
msg: intl.todo( |
|
|
'No tag found, nothing to remove' |
|
|
) |
|
|
}); |
|
|
} |
|
|
|
|
|
engine.tagCollection.remove(tagToRemove); |
|
|
delete engine.refs[tagID]; |
|
|
|
|
|
engine.gitVisuals.refreshTree(); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (generalArgs.length === 0) { |
|
|
var tags = engine.getTags(); |
|
|
engine.printTags(tags); |
|
|
return; |
|
|
} |
|
|
|
|
|
command.twoArgsImpliedHead(generalArgs); |
|
|
engine.tag(generalArgs[0], generalArgs[1]); |
|
|
} |
|
|
}, |
|
|
|
|
|
switch: { |
|
|
sc: /^(gsw|git sw)($|\s)/, |
|
|
regex: /^git +switch($|\s)/, |
|
|
options: [ |
|
|
'-c', |
|
|
'-' |
|
|
], |
|
|
execute: function(engine, command) { |
|
|
var generalArgs = command.getGeneralArgs(); |
|
|
var commandOptions = command.getOptionsMap(); |
|
|
|
|
|
var args = null; |
|
|
if (commandOptions['-c']) { |
|
|
|
|
|
|
|
|
args = commandOptions['-c'].concat(generalArgs); |
|
|
command.twoArgsImpliedHead(args, '-c'); |
|
|
|
|
|
var validId = engine.validateBranchName(args[0]); |
|
|
engine.branch(validId, args[1]); |
|
|
engine.checkout(validId); |
|
|
return; |
|
|
} |
|
|
|
|
|
if (commandOptions['-']) { |
|
|
|
|
|
var lastPlace = engine.HEAD.get('lastLastTarget'); |
|
|
if (!lastPlace) { |
|
|
throw new GitError({ |
|
|
msg: intl.str('git-result-nothing') |
|
|
}); |
|
|
} |
|
|
engine.HEAD.set('target', lastPlace); |
|
|
return; |
|
|
} |
|
|
|
|
|
command.validateArgBounds(generalArgs, 1, 1); |
|
|
|
|
|
engine.checkout(engine.crappyUnescape(generalArgs[0])); |
|
|
} |
|
|
} |
|
|
}; |
|
|
|
|
|
var instantCommands = [ |
|
|
[/^(git help($|\s)|git$)/, function() { |
|
|
var lines = [ |
|
|
intl.str('git-version'), |
|
|
'<br/>', |
|
|
intl.str('git-usage'), |
|
|
escapeString(intl.str('git-usage-command')), |
|
|
'<br/>', |
|
|
intl.str('git-supported-commands'), |
|
|
'<br/>' |
|
|
]; |
|
|
|
|
|
var commands = require('../commands').commands.getOptionMap()['git']; |
|
|
|
|
|
Object.keys(commands).forEach(function(command) { |
|
|
var commandOptions = commands[command]; |
|
|
lines.push('git ' + command); |
|
|
Object.keys(commandOptions).forEach(function(optionName) { |
|
|
lines.push('\t ' + optionName); |
|
|
}, this); |
|
|
}, this); |
|
|
|
|
|
|
|
|
var msg = lines.join('\n'); |
|
|
msg = msg.replace(/\t/g, ' '); |
|
|
throw new CommandResult({ |
|
|
msg: msg |
|
|
}); |
|
|
}] |
|
|
]; |
|
|
|
|
|
exports.commandConfig = commandConfig; |
|
|
exports.instantCommands = instantCommands; |
|
|
|