986 lines
28 KiB
JavaScript
986 lines
28 KiB
JavaScript
const {GitExecutor} = require('./lib/runners/git-executor');
|
|
|
|
const {Scheduler} = require('./lib/runners/scheduler');
|
|
const {GitLogger} = require('./lib/git-logger');
|
|
const {adhocExecTask, configurationErrorTask} = require('./lib/tasks/task');
|
|
const {NOOP, appendTaskOptions, asArray, filterArray, filterPrimitives, filterString, filterStringOrStringArray, filterType, folderExists, getTrailingOptions, trailingFunctionArgument, trailingOptionsArgument} = require('./lib/utils');
|
|
const {applyPatchTask} = require('./lib/tasks/apply-patch')
|
|
const {branchTask, branchLocalTask, deleteBranchesTask, deleteBranchTask} = require('./lib/tasks/branch');
|
|
const {taskCallback} = require('./lib/task-callback');
|
|
const {checkIsRepoTask} = require('./lib/tasks/check-is-repo');
|
|
const {cloneTask, cloneMirrorTask} = require('./lib/tasks/clone');
|
|
const {addConfigTask, listConfigTask} = require('./lib/tasks/config');
|
|
const {cleanWithOptionsTask, isCleanOptionsArray} = require('./lib/tasks/clean');
|
|
const {commitTask} = require('./lib/tasks/commit');
|
|
const {diffSummaryTask} = require('./lib/tasks/diff');
|
|
const {fetchTask} = require('./lib/tasks/fetch');
|
|
const {hashObjectTask} = require('./lib/tasks/hash-object');
|
|
const {initTask} = require('./lib/tasks/init');
|
|
const {logTask, parseLogOptions} = require('./lib/tasks/log');
|
|
const {mergeTask} = require('./lib/tasks/merge');
|
|
const {moveTask} = require("./lib/tasks/move");
|
|
const {pullTask} = require('./lib/tasks/pull');
|
|
const {pushTagsTask, pushTask} = require('./lib/tasks/push');
|
|
const {addRemoteTask, getRemotesTask, listRemotesTask, remoteTask, removeRemoteTask} = require('./lib/tasks/remote');
|
|
const {getResetMode, resetTask} = require('./lib/tasks/reset');
|
|
const {stashListTask} = require('./lib/tasks/stash-list');
|
|
const {statusTask} = require('./lib/tasks/status');
|
|
const {addSubModuleTask, initSubModuleTask, subModuleTask, updateSubModuleTask} = require('./lib/tasks/sub-module');
|
|
const {addAnnotatedTagTask, addTagTask, tagListTask} = require('./lib/tasks/tag');
|
|
const {straightThroughStringTask} = require('./lib/tasks/task');
|
|
const {parseCheckIgnore} = require('./lib/responses/CheckIgnore');
|
|
|
|
const ChainedExecutor = Symbol('ChainedExecutor');
|
|
|
|
/**
|
|
* Git handling for node. All public functions can be chained and all `then` handlers are optional.
|
|
*
|
|
* @param {SimpleGitOptions} options Configuration settings for this instance
|
|
*
|
|
* @constructor
|
|
*/
|
|
function Git (options) {
|
|
this._executor = new GitExecutor(
|
|
options.binary, options.baseDir,
|
|
new Scheduler(options.maxConcurrentProcesses)
|
|
);
|
|
this._logger = new GitLogger();
|
|
}
|
|
|
|
/**
|
|
* The executor that runs each of the added commands
|
|
* @type {GitExecutor}
|
|
* @private
|
|
*/
|
|
Git.prototype._executor = null;
|
|
|
|
/**
|
|
* Logging utility for printing out info or error messages to the user
|
|
* @type {GitLogger}
|
|
* @private
|
|
*/
|
|
Git.prototype._logger = null;
|
|
|
|
/**
|
|
* Sets the path to a custom git binary, should either be `git` when there is an installation of git available on
|
|
* the system path, or a fully qualified path to the executable.
|
|
*
|
|
* @param {string} command
|
|
* @returns {Git}
|
|
*/
|
|
Git.prototype.customBinary = function (command) {
|
|
this._executor.binary = command;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Sets an environment variable for the spawned child process, either supply both a name and value as strings or
|
|
* a single object to entirely replace the current environment variables.
|
|
*
|
|
* @param {string|Object} name
|
|
* @param {string} [value]
|
|
* @returns {Git}
|
|
*/
|
|
Git.prototype.env = function (name, value) {
|
|
if (arguments.length === 1 && typeof name === 'object') {
|
|
this._executor.env = name;
|
|
} else {
|
|
(this._executor.env = this._executor.env || {})[name] = value;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Sets the working directory of the subsequent commands.
|
|
*/
|
|
Git.prototype.cwd = function (workingDirectory) {
|
|
const task = (typeof workingDirectory !== 'string')
|
|
? configurationErrorTask('Git.cwd: workingDirectory must be supplied as a string')
|
|
: adhocExecTask(() => {
|
|
if (!folderExists(workingDirectory)) {
|
|
throw new Error(`Git.cwd: cannot change to non-directory "${ workingDirectory }"`);
|
|
}
|
|
|
|
return (this._executor.cwd = workingDirectory);
|
|
});
|
|
|
|
return this._runTask(task, trailingFunctionArgument(arguments) || NOOP);
|
|
};
|
|
|
|
/**
|
|
* Sets a handler function to be called whenever a new child process is created, the handler function will be called
|
|
* with the name of the command being run and the stdout & stderr streams used by the ChildProcess.
|
|
*
|
|
* @example
|
|
* require('simple-git')
|
|
* .outputHandler(function (command, stdout, stderr) {
|
|
* stdout.pipe(process.stdout);
|
|
* })
|
|
* .checkout('https://github.com/user/repo.git');
|
|
*
|
|
* @see https://nodejs.org/api/child_process.html#child_process_class_childprocess
|
|
* @see https://nodejs.org/api/stream.html#stream_class_stream_readable
|
|
* @param {Function} outputHandler
|
|
* @returns {Git}
|
|
*/
|
|
Git.prototype.outputHandler = function (outputHandler) {
|
|
this._executor.outputHandler = outputHandler;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Initialize a git repo
|
|
*
|
|
* @param {Boolean} [bare=false]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.init = function (bare, then) {
|
|
return this._runTask(
|
|
initTask(bare === true, this._executor.cwd, getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Check the status of the local repo
|
|
*/
|
|
Git.prototype.status = function () {
|
|
return this._runTask(
|
|
statusTask(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* List the stash(s) of the local repo
|
|
*/
|
|
Git.prototype.stashList = function (options) {
|
|
return this._runTask(
|
|
stashListTask(
|
|
trailingOptionsArgument(arguments) || {},
|
|
filterArray(options) && options || []
|
|
),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Stash the local repo
|
|
*
|
|
* @param {Object|Array} [options]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.stash = function (options, then) {
|
|
return this._runTask(
|
|
straightThroughStringTask(['stash', ...getTrailingOptions(arguments)]),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
function createCloneTask (api, task, repoPath, localPath) {
|
|
if (typeof repoPath !== 'string') {
|
|
return configurationErrorTask(`git.${ api }() requires a string 'repoPath'`);
|
|
}
|
|
|
|
return task(repoPath, filterType(localPath, filterString), getTrailingOptions(arguments));
|
|
}
|
|
|
|
|
|
/**
|
|
* Clone a git repo
|
|
*/
|
|
Git.prototype.clone = function () {
|
|
return this._runTask(
|
|
createCloneTask('clone', cloneTask, ...arguments),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Mirror a git repo
|
|
*/
|
|
Git.prototype.mirror = function () {
|
|
return this._runTask(
|
|
createCloneTask('mirror', cloneMirrorTask, ...arguments),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Moves one or more files to a new destination.
|
|
*
|
|
* @see https://git-scm.com/docs/git-mv
|
|
*
|
|
* @param {string|string[]} from
|
|
* @param {string} to
|
|
*/
|
|
Git.prototype.mv = function (from, to) {
|
|
return this._runTask(moveTask(from, to), trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Internally uses pull and tags to get the list of tags then checks out the latest tag.
|
|
*
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.checkoutLatestTag = function (then) {
|
|
var git = this;
|
|
return this.pull(function () {
|
|
git.tags(function (err, tags) {
|
|
git.checkout(tags.latest, then);
|
|
});
|
|
});
|
|
};
|
|
|
|
/**
|
|
* Adds one or more files to source control
|
|
*/
|
|
Git.prototype.add = function (files) {
|
|
return this._run(
|
|
['add'].concat(files),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Commits changes in the current working directory - when specific file paths are supplied, only changes on those
|
|
* files will be committed.
|
|
*
|
|
* @param {string|string[]} message
|
|
* @param {string|string[]} [files]
|
|
* @param {Object} [options]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.commit = function (message, files, options, then) {
|
|
const next = trailingFunctionArgument(arguments);
|
|
const messages = [];
|
|
|
|
if (filterStringOrStringArray(message)) {
|
|
messages.push(...asArray(message));
|
|
}
|
|
else {
|
|
console.warn('simple-git deprecation notice: git.commit: requires the commit message to be supplied as a string/string[], this will be an error in version 3');
|
|
}
|
|
|
|
return this._runTask(
|
|
commitTask(
|
|
messages,
|
|
asArray(filterType(files, filterStringOrStringArray, [])),
|
|
[...filterType(options, filterArray, []), ...getTrailingOptions(arguments, 0, true)]
|
|
),
|
|
next
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Pull the updated contents of the current repo
|
|
*/
|
|
Git.prototype.pull = function (remote, branch, options, then) {
|
|
return this._runTask(
|
|
pullTask(filterType(remote, filterString), filterType(branch, filterString), getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Fetch the updated contents of the current repo.
|
|
*
|
|
* @example
|
|
* .fetch('upstream', 'master') // fetches from master on remote named upstream
|
|
* .fetch(function () {}) // runs fetch against default remote and branch and calls function
|
|
*
|
|
* @param {string} [remote]
|
|
* @param {string} [branch]
|
|
*/
|
|
Git.prototype.fetch = function (remote, branch) {
|
|
return this._runTask(
|
|
fetchTask(filterType(remote, filterString), filterType(branch, filterString), getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Disables/enables the use of the console for printing warnings and errors, by default messages are not shown in
|
|
* a production environment.
|
|
*
|
|
* @param {boolean} silence
|
|
* @returns {Git}
|
|
*/
|
|
Git.prototype.silent = function (silence) {
|
|
this._logger.silent(!!silence);
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* List all tags. When using git 2.7.0 or above, include an options object with `"--sort": "property-name"` to
|
|
* sort the tags by that property instead of using the default semantic versioning sort.
|
|
*
|
|
* Note, supplying this option when it is not supported by your Git version will cause the operation to fail.
|
|
*
|
|
* @param {Object} [options]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.tags = function (options, then) {
|
|
return this._runTask(
|
|
tagListTask(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Rebases the current working copy. Options can be supplied either as an array of string parameters
|
|
* to be sent to the `git rebase` command, or a standard options object.
|
|
*/
|
|
Git.prototype.rebase = function () {
|
|
return this._run(
|
|
['rebase'].concat(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments)
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Reset a repo
|
|
*
|
|
* @param {string|string[]} [mode=soft] Either an array of arguments supported by the 'git reset' command, or the
|
|
* string value 'soft' or 'hard' to set the reset mode.
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.reset = function (mode, then) {
|
|
return this._runTask(
|
|
resetTask(getResetMode(mode), getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Revert one or more commits in the local working copy
|
|
*/
|
|
Git.prototype.revert = function (commit) {
|
|
const next = trailingFunctionArgument(arguments);
|
|
|
|
if (typeof commit !== 'string') {
|
|
return this._runTask(
|
|
configurationErrorTask('Commit must be a string'),
|
|
next,
|
|
);
|
|
}
|
|
|
|
return this._run([
|
|
'revert',
|
|
...getTrailingOptions(arguments, 0, true),
|
|
commit
|
|
], next);
|
|
};
|
|
|
|
/**
|
|
* Add a lightweight tag to the head of the current branch
|
|
*
|
|
* @param {string} name
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.addTag = function (name, then) {
|
|
const task = (typeof name === 'string')
|
|
? addTagTask(name)
|
|
: configurationErrorTask('Git.addTag requires a tag name');
|
|
|
|
return this._runTask(task, trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Add an annotated tag to the head of the current branch
|
|
*
|
|
* @param {string} tagName
|
|
* @param {string} tagMessage
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.addAnnotatedTag = function (tagName, tagMessage, then) {
|
|
return this._runTask(
|
|
addAnnotatedTagTask(tagName, tagMessage),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Check out a tag or revision, any number of additional arguments can be passed to the `git checkout` command
|
|
* by supplying either a string or array of strings as the `what` parameter.
|
|
*
|
|
* @param {string|string[]} what One or more commands to pass to `git checkout`
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.checkout = function (what, then) {
|
|
const commands = ['checkout', ...getTrailingOptions(arguments, true)];
|
|
return this._runTask(
|
|
straightThroughStringTask(commands),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Check out a remote branch
|
|
*
|
|
* @param {string} branchName name of branch
|
|
* @param {string} startPoint (e.g origin/development)
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.checkoutBranch = function (branchName, startPoint, then) {
|
|
return this.checkout(['-b', branchName, startPoint], trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Check out a local branch
|
|
*/
|
|
Git.prototype.checkoutLocalBranch = function (branchName, then) {
|
|
return this.checkout(['-b', branchName], trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Delete a local branch
|
|
*/
|
|
Git.prototype.deleteLocalBranch = function (branchName, forceDelete, then) {
|
|
return this._runTask(
|
|
deleteBranchTask(branchName, typeof forceDelete === "boolean" ? forceDelete : false),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Delete one or more local branches
|
|
*/
|
|
Git.prototype.deleteLocalBranches = function (branchNames, forceDelete, then) {
|
|
return this._runTask(
|
|
deleteBranchesTask(branchNames, typeof forceDelete === "boolean" ? forceDelete : false),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* List all branches
|
|
*
|
|
* @param {Object | string[]} [options]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.branch = function (options, then) {
|
|
return this._runTask(
|
|
branchTask(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Return list of local branches
|
|
*
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.branchLocal = function (then) {
|
|
return this._runTask(
|
|
branchLocalTask(),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Add config to local git instance
|
|
*
|
|
* @param {string} key configuration key (e.g user.name)
|
|
* @param {string} value for the given key (e.g your name)
|
|
* @param {boolean} [append=false] optionally append the key/value pair (equivalent of passing `--add` option).
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.addConfig = function (key, value, append, then) {
|
|
return this._runTask(
|
|
addConfigTask(key, value, typeof append === "boolean" ? append : false),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype.listConfig = function () {
|
|
return this._runTask(listConfigTask(), trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Executes any command against the git binary.
|
|
*/
|
|
Git.prototype.raw = function (commands) {
|
|
const createRestCommands = !Array.isArray(commands);
|
|
const command = [].slice.call(createRestCommands ? arguments : commands, 0);
|
|
|
|
for (let i = 0; i < command.length && createRestCommands; i++) {
|
|
if (!filterPrimitives(command[i])) {
|
|
command.splice(i, command.length - i);
|
|
break;
|
|
}
|
|
}
|
|
|
|
command.push(
|
|
...getTrailingOptions(arguments, 0, true),
|
|
);
|
|
|
|
var next = trailingFunctionArgument(arguments);
|
|
|
|
if (!command.length) {
|
|
return this._runTask(
|
|
configurationErrorTask('Raw: must supply one or more command to execute'),
|
|
next,
|
|
);
|
|
}
|
|
|
|
return this._run(command, next);
|
|
};
|
|
|
|
Git.prototype.submoduleAdd = function (repo, path, then) {
|
|
return this._runTask(
|
|
addSubModuleTask(repo, path),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype.submoduleUpdate = function (args, then) {
|
|
return this._runTask(
|
|
updateSubModuleTask(getTrailingOptions(arguments, true)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype.submoduleInit = function (args, then) {
|
|
return this._runTask(
|
|
initSubModuleTask(getTrailingOptions(arguments, true)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype.subModule = function (options, then) {
|
|
return this._runTask(
|
|
subModuleTask(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype.listRemote = function () {
|
|
return this._runTask(
|
|
listRemotesTask(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Adds a remote to the list of remotes.
|
|
*/
|
|
Git.prototype.addRemote = function (remoteName, remoteRepo, then) {
|
|
return this._runTask(
|
|
addRemoteTask(remoteName, remoteRepo, getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Removes an entry by name from the list of remotes.
|
|
*/
|
|
Git.prototype.removeRemote = function (remoteName, then) {
|
|
return this._runTask(
|
|
removeRemoteTask(remoteName),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Gets the currently available remotes, setting the optional verbose argument to true includes additional
|
|
* detail on the remotes themselves.
|
|
*/
|
|
Git.prototype.getRemotes = function (verbose, then) {
|
|
return this._runTask(
|
|
getRemotesTask(verbose === true),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Compute object ID from a file
|
|
*/
|
|
Git.prototype.hashObject = function (path, write) {
|
|
return this._runTask(
|
|
hashObjectTask(path, write === true),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Call any `git remote` function with arguments passed as an array of strings.
|
|
*
|
|
* @param {string[]} options
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.remote = function (options, then) {
|
|
return this._runTask(
|
|
remoteTask(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Merges from one branch to another, equivalent to running `git merge ${from} $[to}`, the `options` argument can
|
|
* either be an array of additional parameters to pass to the command or null / omitted to be ignored.
|
|
*
|
|
* @param {string} from
|
|
* @param {string} to
|
|
*/
|
|
Git.prototype.mergeFromTo = function (from, to) {
|
|
if (!(filterString(from) && filterString(to))) {
|
|
return this._runTask(configurationErrorTask(
|
|
`Git.mergeFromTo requires that the 'from' and 'to' arguments are supplied as strings`
|
|
));
|
|
}
|
|
|
|
return this._runTask(
|
|
mergeTask([from, to, ...getTrailingOptions(arguments)]),
|
|
trailingFunctionArgument(arguments, false),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Runs a merge, `options` can be either an array of arguments
|
|
* supported by the [`git merge`](https://git-scm.com/docs/git-merge)
|
|
* or an options object.
|
|
*
|
|
* Conflicts during the merge result in an error response,
|
|
* the response type whether it was an error or success will be a MergeSummary instance.
|
|
* When successful, the MergeSummary has all detail from a the PullSummary
|
|
*
|
|
* @param {Object | string[]} [options]
|
|
* @param {Function} [then]
|
|
* @returns {*}
|
|
*
|
|
* @see ./responses/MergeSummary.js
|
|
* @see ./responses/PullSummary.js
|
|
*/
|
|
Git.prototype.merge = function () {
|
|
return this._runTask(
|
|
mergeTask(getTrailingOptions(arguments)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Call any `git tag` function with arguments passed as an array of strings.
|
|
*
|
|
* @param {string[]} options
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.tag = function (options, then) {
|
|
const command = getTrailingOptions(arguments);
|
|
|
|
if (command[0] !== 'tag') {
|
|
command.unshift('tag');
|
|
}
|
|
|
|
return this._run(command, trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Updates repository server info
|
|
*
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.updateServerInfo = function (then) {
|
|
return this._run(["update-server-info"], trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Pushes the current committed changes to a remote, optionally specify the names of the remote and branch to use
|
|
* when pushing. Supply multiple options as an array of strings in the first argument - see examples below.
|
|
*/
|
|
Git.prototype.push = function (remote, branch, then) {
|
|
const task = pushTask(
|
|
{remote: filterType(remote, filterString), branch: filterType(branch, filterString)},
|
|
getTrailingOptions(arguments),
|
|
);
|
|
return this._runTask(task, trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Pushes the current tag changes to a remote which can be either a URL or named remote. When not specified uses the
|
|
* default configured remote spec.
|
|
*
|
|
* @param {string} [remote]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.pushTags = function (remote, then) {
|
|
const task = pushTagsTask({remote: filterType(remote, filterString)}, getTrailingOptions(arguments));
|
|
|
|
return this._runTask(task, trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Removes the named files from source control.
|
|
*
|
|
* @param {string|string[]} files
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.rm = function (files, then) {
|
|
return this._rm(files, '-f', then);
|
|
};
|
|
|
|
/**
|
|
* Removes the named files from source control but keeps them on disk rather than deleting them entirely. To
|
|
* completely remove the files, use `rm`.
|
|
*
|
|
* @param {string|string[]} files
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.rmKeepLocal = function (files, then) {
|
|
return this._rm(files, '--cached', then);
|
|
};
|
|
|
|
/**
|
|
* Returns a list of objects in a tree based on commit hash. Passing in an object hash returns the object's content,
|
|
* size, and type.
|
|
*
|
|
* Passing "-p" will instruct cat-file to determine the object type, and display its formatted contents.
|
|
*
|
|
* @param {string[]} [options]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.catFile = function (options, then) {
|
|
return this._catFile('utf-8', arguments);
|
|
};
|
|
|
|
/**
|
|
* Equivalent to `catFile` but will return the native `Buffer` of content from the git command's stdout.
|
|
*
|
|
* @param {string[]} options
|
|
* @param then
|
|
*/
|
|
Git.prototype.binaryCatFile = function (options, then) {
|
|
return this._catFile('buffer', arguments);
|
|
};
|
|
|
|
Git.prototype._catFile = function (format, args) {
|
|
var handler = trailingFunctionArgument(args);
|
|
var command = ['cat-file'];
|
|
var options = args[0];
|
|
|
|
if (typeof options === 'string') {
|
|
return this._runTask(
|
|
configurationErrorTask('Git#catFile: options must be supplied as an array of strings'),
|
|
handler,
|
|
);
|
|
}
|
|
|
|
if (Array.isArray(options)) {
|
|
command.push.apply(command, options);
|
|
}
|
|
|
|
return this._run(command, handler, {
|
|
format: format
|
|
});
|
|
};
|
|
|
|
Git.prototype.diff = function (options, then) {
|
|
const command = ['diff', ...getTrailingOptions(arguments)];
|
|
|
|
if (typeof options === 'string') {
|
|
command.splice(1, 0, options);
|
|
this._logger.warn('Git#diff: supplying options as a single string is now deprecated, switch to an array of strings');
|
|
}
|
|
|
|
return this._runTask(
|
|
straightThroughStringTask(command),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype.diffSummary = function () {
|
|
return this._runTask(
|
|
diffSummaryTask(getTrailingOptions(arguments, 1)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype.applyPatch = function(patches) {
|
|
const task = !filterStringOrStringArray(patches)
|
|
? configurationErrorTask(`git.applyPatch requires one or more string patches as the first argument`)
|
|
: applyPatchTask(asArray(patches), getTrailingOptions([].slice.call(arguments, 1)));
|
|
|
|
return this._runTask(
|
|
task,
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
}
|
|
|
|
Git.prototype.revparse = function () {
|
|
const commands = ['rev-parse', ...getTrailingOptions(arguments, true)];
|
|
return this._runTask(
|
|
straightThroughStringTask(commands, true),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Show various types of objects, for example the file at a certain commit
|
|
*
|
|
* @param {string[]} [options]
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.show = function (options, then) {
|
|
return this._runTask(
|
|
straightThroughStringTask(['show', ...getTrailingOptions(arguments, 1)]),
|
|
trailingFunctionArgument(arguments)
|
|
);
|
|
};
|
|
|
|
/**
|
|
*/
|
|
Git.prototype.clean = function (mode, options, then) {
|
|
const usingCleanOptionsArray = isCleanOptionsArray(mode);
|
|
const cleanMode = usingCleanOptionsArray && mode.join('') || filterType(mode, filterString) || '';
|
|
const customArgs = getTrailingOptions([].slice.call(arguments, usingCleanOptionsArray ? 1 : 0));
|
|
|
|
return this._runTask(
|
|
cleanWithOptionsTask(cleanMode, customArgs),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
/**
|
|
* Call a simple function at the next step in the chain.
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.exec = function (then) {
|
|
const task = {
|
|
commands: [],
|
|
format: 'utf-8',
|
|
parser () {
|
|
if (typeof then === 'function') {
|
|
then();
|
|
}
|
|
}
|
|
};
|
|
|
|
return this._runTask(task);
|
|
};
|
|
|
|
/**
|
|
* Show commit logs from `HEAD` to the first commit.
|
|
* If provided between `options.from` and `options.to` tags or branch.
|
|
*
|
|
* Additionally you can provide options.file, which is the path to a file in your repository. Then only this file will be considered.
|
|
*
|
|
* To use a custom splitter in the log format, set `options.splitter` to be the string the log should be split on.
|
|
*
|
|
* Options can also be supplied as a standard options object for adding custom properties supported by the git log command.
|
|
* For any other set of options, supply options as an array of strings to be appended to the git log command.
|
|
*/
|
|
Git.prototype.log = function (options) {
|
|
const next = trailingFunctionArgument(arguments);
|
|
|
|
if (filterString(arguments[0]) && filterString(arguments[1])) {
|
|
return this._runTask(
|
|
configurationErrorTask(`git.log(string, string) should be replaced with git.log({ from: string, to: string })`),
|
|
next
|
|
);
|
|
}
|
|
|
|
const parsedOptions = parseLogOptions(
|
|
trailingOptionsArgument(arguments) || {},
|
|
filterArray(options) && options || []
|
|
);
|
|
|
|
return this._runTask(
|
|
logTask(parsedOptions.splitter, parsedOptions.fields, parsedOptions.commands),
|
|
next,
|
|
)
|
|
};
|
|
|
|
/**
|
|
* Clears the queue of pending commands and returns the wrapper instance for chaining.
|
|
*
|
|
* @returns {Git}
|
|
*/
|
|
Git.prototype.clearQueue = function () {
|
|
// TODO:
|
|
// this._executor.clear();
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* Check if a pathname or pathnames are excluded by .gitignore
|
|
*
|
|
* @param {string|string[]} pathnames
|
|
* @param {Function} [then]
|
|
*/
|
|
Git.prototype.checkIgnore = function (pathnames, then) {
|
|
return this._run(
|
|
["check-ignore", ...asArray((filterType(pathnames, filterStringOrStringArray, [])))],
|
|
trailingFunctionArgument(arguments),
|
|
{
|
|
parser: parseCheckIgnore
|
|
}
|
|
)
|
|
};
|
|
|
|
Git.prototype.checkIsRepo = function (checkType, then) {
|
|
return this._runTask(
|
|
checkIsRepoTask(filterType(checkType, filterString)),
|
|
trailingFunctionArgument(arguments),
|
|
);
|
|
};
|
|
|
|
Git.prototype._rm = function (_files, options, then) {
|
|
var files = [].concat(_files);
|
|
var args = ['rm', options];
|
|
args.push.apply(args, files);
|
|
|
|
return this._run(args, trailingFunctionArgument(arguments));
|
|
};
|
|
|
|
/**
|
|
* Schedules the supplied command to be run, the command should not include the name of the git binary and should
|
|
* be an array of strings passed as the arguments to the git binary.
|
|
*
|
|
* @param {string[]} command
|
|
* @param {Function} then
|
|
* @param {Object} [opt]
|
|
* @param {boolean} [opt.concatStdErr=false] Optionally concatenate stderr output into the stdout
|
|
* @param {boolean} [opt.format="utf-8"] The format to use when reading the content of stdout
|
|
* @param {Function} [opt.onError] Optional error handler for this command - can be used to allow non-clean exits
|
|
* without killing the remaining stack of commands
|
|
* @param {Function} [opt.parser] Optional parser function
|
|
* @param {number} [opt.onError.exitCode]
|
|
* @param {string} [opt.onError.stdErr]
|
|
*
|
|
* @returns {Git}
|
|
*/
|
|
Git.prototype._run = function (command, then, opt) {
|
|
|
|
const task = Object.assign({
|
|
concatStdErr: false,
|
|
onError: undefined,
|
|
format: 'utf-8',
|
|
parser (data) {
|
|
return data;
|
|
}
|
|
}, opt || {}, {
|
|
commands: command,
|
|
});
|
|
|
|
return this._runTask(task, then);
|
|
};
|
|
|
|
Git.prototype._runTask = function (task, then) {
|
|
const executor = this[ChainedExecutor] || this._executor.chain();
|
|
const promise = executor.push(task);
|
|
|
|
taskCallback(
|
|
task,
|
|
promise,
|
|
then);
|
|
|
|
return Object.create(this, {
|
|
then: {value: promise.then.bind(promise)},
|
|
catch: {value: promise.catch.bind(promise)},
|
|
[ChainedExecutor]: {value: executor},
|
|
});
|
|
};
|
|
|
|
module.exports = Git;
|