Socket
Socket
Sign inDemoInstall

simple-git

Package Overview
Dependencies
Maintainers
1
Versions
259
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

simple-git - npm Package Compare versions

Comparing version 1.14.0 to 1.15.0

12

GruntFile.js

@@ -8,2 +8,6 @@ module.exports = function (grunt) {

nodeunit: {
all: ['test/test*.js']
},
release: {

@@ -19,2 +23,3 @@ options: {

grunt.loadNpmTasks('grunt-contrib-nodeunit');
grunt.loadNpmTasks('grunt-release-steps');

@@ -26,8 +31,9 @@

grunt.registerTask('patch', ['release:bump:patch', '-to-git']);
grunt.registerTask('minor', ['release:bump:minor', '-tag', '-to-git', '-to-npm']);
grunt.registerTask('major', ['release:bump:major', '-tag', '-to-git', '-to-npm']);
grunt.registerTask('patch', ['test', 'release:bump:patch', '-to-git']);
grunt.registerTask('minor', ['test', 'release:bump:minor', '-tag', '-to-git', '-to-npm']);
grunt.registerTask('major', ['test', 'release:bump:major', '-tag', '-to-git', '-to-npm']);
grunt.registerTask('default', ['patch']);
grunt.registerTask('test', ['nodeunit:all']);
};
{
"name": "simple-git",
"description": "Simple GIT interface for node.js",
"version": "1.14.0",
"version": "1.15.0",
"author": "Steve King <steve@mydev.co>",

@@ -15,2 +15,3 @@ "contributors": [

"grunt": "~0.4.1",
"grunt-contrib-nodeunit": "^0.4.1",
"grunt-release-steps": "~0.3.7",

@@ -17,0 +18,0 @@ "nodeunit": "^0.9.1",

@@ -44,2 +44,4 @@ # Simple Git

`.addAnnotatedTag(tagName, tagMessage, handlerFn)` adds an annotated tag to the head of the current branch
`.log([options], handlerFn)` list commits between `options.from` and `options.to` tags or branch

@@ -46,0 +48,0 @@ (if not specified will show all history). Additionally you can provide `options.file`, which is the path to a file in

(function () {
/**
* Git handling for node. All public functions can be chained and all `then` handlers are optional.
*
* @param {String} baseDir base directory for all processes to run
*
* @param {Function} ChildProcess The ChildProcess constructor to use
* @param {Function} Buffer The Buffer implementation to use
*
* @constructor
*/
function Git (baseDir, ChildProcess, Buffer) {
this._baseDir = baseDir;
this._runCache = [];
/**
* Git handling for node. All public functions can be chained and all `then` handlers are optional.
*
* @param {string} baseDir base directory for all processes to run
*
* @param {Function} ChildProcess The ChildProcess constructor to use
* @param {Function} Buffer The Buffer implementation to use
*
* @constructor
*/
function Git (baseDir, ChildProcess, Buffer) {
this._baseDir = baseDir;
this._runCache = [];
this.ChildProcess = ChildProcess;
this.Buffer = Buffer;
}
this.ChildProcess = ChildProcess;
this.Buffer = Buffer;
}
/**
* @type {string} The command to use to reference the git binary
*/
Git.prototype._command = 'git';
/**
* @type {string} The command to use to reference the git binary
*/
Git.prototype._command = 'git';
/**
* @type {Function} An optional handler to use when a child process is created
*/
Git.prototype._outputHandler = null;
/**
* @type {Function} An optional handler to use when a child process is created
*/
Git.prototype._outputHandler = null;
/**
* @type {boolean} Property showing whether logging will be silenced - defaults to true in a production environment
*/
Git.prototype._silentLogging = /prod/.test(process.env.NODE_ENV);
/**
* @type {boolean} Property showing whether logging will be silenced - defaults to true in a production environment
*/
Git.prototype._silentLogging = /prod/.test(process.env.NODE_ENV);
/**
* 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._command = command;
return this;
};
/**
* 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._command = command;
return this;
};
/**
* 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) {
/**
* 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 http://nodejs.org/api/child_process.html#child_process_class_childprocess
* @see http://nodejs.org/api/stream.html#stream_class_stream_readable
* @param {Function} outputHandler
* @returns {Git}
*/
Git.prototype.outputHandler = function (outputHandler) {
this._outputHandler = outputHandler;
return this;
};
* .checkout('https://github.com/user/repo.git');
*
* @see http://nodejs.org/api/child_process.html#child_process_class_childprocess
* @see http://nodejs.org/api/stream.html#stream_class_stream_readable
* @param {Function} outputHandler
* @returns {Git}
*/
Git.prototype.outputHandler = function (outputHandler) {
this._outputHandler = outputHandler;
return this;
};
/**
* Initialize a git repo
*
* @param {Boolean} [bare=false]
* @param {Function} [then]
*/
Git.prototype.init = function (bare, then) {
var commands = ['init'];
var next = Git.trailingFunctionArgument(arguments);
/**
* Initialize a git repo
*
* @param {Boolean} [bare=false]
* @param {Function} [then]
*/
Git.prototype.init = function (bare, then) {
var commands = ['init'];
var next = Git.trailingFunctionArgument(arguments);
if (bare === true) {
commands.push('--bare');
}
if (bare === true) {
commands.push('--bare');
}
return this._run(commands, function (err) {
next && next(err);
});
};
return this._run(commands, function (err) {
next && next(err);
});
};
/**
* Check the status of the local repo
*
* @param {Function} [then]
*/
Git.prototype.status = function (then) {
return this._run(['status', '--porcelain'], function (err, data) {
then && then(err, !err && this._parseStatus(data));
});
};
/**
* Check the status of the local repo
*
* @param {Function} [then]
*/
Git.prototype.status = function (then) {
return this._run(['status', '--porcelain'], function (err, data) {
then && then(err, !err && this._parseStatus(data));
});
};
/**
* Clone a git repo
*
* @param {String} repoPath
* @param {String} localPath
* @param {Function} [then]
*/
Git.prototype.clone = function (repoPath, localPath, then) {
return this._run(['clone', repoPath, localPath], function (err) {
then && then(err);
});
};
/**
* Clone a git repo
*
* @param {string} repoPath
* @param {string} localPath
* @param {Function} [then]
*/
Git.prototype.clone = function (repoPath, localPath, then) {
return this._run(['clone', repoPath, localPath], function (err) {
then && then(err);
});
};
/**
* 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().tags(function (err, tags) {
git.checkout(tags.latest, then);
});
};
/**
* 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().tags(function (err, tags) {
git.checkout(tags.latest, then);
});
};
/**
* Adds one or more files to source control
*
* @param {String|String[]} files
* @param {Function} [then]
*/
Git.prototype.add = function (files, then) {
return this._run(['add'].concat(files), function (err, data) {
then && then(err);
});
};
/**
* Adds one or more files to source control
*
* @param {string|string[]} files
* @param {Function} [then]
*/
Git.prototype.add = function (files, then) {
return this._run(['add'].concat(files), function (err, data) {
then && then(err);
});
};
/**
* Commits changes in the current working directory - when specific file paths are supplied, only changes on those
* files will be committed.
*
* @param {String} message
* @param {String|String[]} [files]
* @param {Function} [then]
*/
Git.prototype.commit = function (message, files, then) {
var git = this;
if (!then && typeof files === "function") {
then = files;
files = [];
}
/**
* Commits changes in the current working directory - when specific file paths are supplied, only changes on those
* files will be committed.
*
* @param {string} message
* @param {string|string[]} [files]
* @param {Function} [then]
*/
Git.prototype.commit = function (message, files, then) {
var git = this;
if (!then && typeof files === "function") {
then = files;
files = [];
}
return this._run(['commit', '-m', message].concat([].concat(files || [])), function (err, data) {
then && then(err, !err && require('./CommitSummary').parse(data));
});
};
return this._run(['commit', '-m', message].concat([].concat(files || [])), function (err, data) {
then && then(err, !err && require('./CommitSummary').parse(data));
});
};
/**
* Gets a function to be used for logging.
*
* @param {string} level
* @param {string} [message]
*
* @returns {Function}
* @private
*/
Git.prototype._getLog = function (level, message) {
var log = this._silentLogging ? function () {} : console[level].bind(console);
if (arguments.length > 1) {
log(message);
}
return log;
};
/**
* Gets a function to be used for logging.
*
* @param {string} level
* @param {string} [message]
*
* @returns {Function}
* @private
*/
Git.prototype._getLog = function (level, message) {
var log = this._silentLogging ? function () {
} : console[level].bind(console);
if (arguments.length > 1) {
log(message);
}
return log;
};
/**
* Pull the updated contents of the current repo
* @param {String} [remote]
* @param {String} [branch]
* @param {Function} [then]
*/
Git.prototype.pull = function (remote, branch, then) {
var command = ["pull"];
if (typeof remote === 'string' && typeof branch === 'string') {
command.push(remote, branch);
}
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
/**
* Pull the updated contents of the current repo
* @param {string} [remote]
* @param {string} [branch]
* @param {Function} [then]
*/
Git.prototype.pull = function (remote, branch, then) {
var command = ["pull"];
if (typeof remote === 'string' && typeof branch === 'string') {
command.push(remote, branch);
}
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
return this._run(command, function (err, data) {
then && then(err, !err && this._parsePull(data));
});
};
return this._run(command, function (err, data) {
then && then(err, !err && this._parsePull(data));
});
};
/**
* 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]
* @param {Function} [then]
*/
Git.prototype.fetch = function (remote, branch, then) {
var command = ["fetch"];
if (typeof remote === 'string' && typeof branch === 'string') {
command.push(remote, branch);
}
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
/**
* 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]
* @param {Function} [then]
*/
Git.prototype.fetch = function (remote, branch, then) {
var command = ["fetch"];
if (typeof remote === 'string' && typeof branch === 'string') {
command.push(remote, branch);
}
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
return this._run(command, function (err, data) {
then && then(err, !err && this._parseFetch(data));
});
};
return this._run(command, function (err, data) {
then && then(err, !err && this._parseFetch(data));
});
};
/**
* 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._silentLogging = !!silence;
return this;
};
/**
* 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._silentLogging = !!silence;
return this;
};
/**
* List all tags
*
* @param {Function} [then]
*/
Git.prototype.tags = function (then) {
return this._run(['tag', '-l'], function (err, data) {
then && then(err, !err && this._parseListTags(data));
});
};
/**
* List all tags
*
* @param {Function} [then]
*/
Git.prototype.tags = function (then) {
return this.tag(['-l'], function (err, data) {
then && then(err, !err && this._parseListTags(data));
});
};
/**
* Reset a repo
*
* @param {string} [mode=soft] Either 'soft' or 'hard'
* @param {Function} [then]
*/
Git.prototype.reset = function (mode, then) {
var resetMode = '--' + (mode === 'hard' ? mode : 'soft');
var next = (typeof arguments[arguments.length - 1] === "function") ? arguments[arguments.length - 1] : null;
/**
* Reset a repo
*
* @param {string} [mode=soft] Either 'soft' or 'hard'
* @param {Function} [then]
*/
Git.prototype.reset = function (mode, then) {
var resetMode = '--' + (mode === 'hard' ? mode : 'soft');
var next = (typeof arguments[arguments.length - 1] === "function") ? arguments[arguments.length - 1] : null;
return this._run(['reset', resetMode], function (err) {
next && next(err || null);
});
};
return this._run(['reset', resetMode], function (err) {
next && next(err || null);
});
};
/**
* Add a lightweight tag to the head of the current branch
*
* @param {String} name
* @param {Function} [then]
*/
Git.prototype.addTag = function (name, then) {
return this._run(['tag', name], function (err) {
then && then(err);
});
};
/**
* Add a lightweight tag to the head of the current branch
*
* @param {string} name
* @param {Function} [then]
*/
Git.prototype.addTag = function (name, then) {
if (typeof name !== "string") {
return this.then(function () {
then && then(new TypeError("Git.addTag requires a tag name"));
});
}
/**
* Check out a tag or revision
*
* @param {String} what
* @param {Function} [then]
*/
Git.prototype.checkout = function (what, then) {
return this._run(['checkout', what], function (err, data) {
then && then(err, !err && this._parseCheckout(data));
});
};
return this.tag([name], then);
};
/**
* 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._run(['checkout', '-b', branchName, startPoint], function (err, data) {
then && then(err, !err && this._parseCheckout(data));
});
};
/**
* 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.tag(['-a', '-m', tagMessage, tagName], function (err) {
then && then(err);
});
};
/**
* Check out a local branch
*
* @param {String} branchName of branch
* @param {Function} [then]
*/
Git.prototype.checkoutLocalBranch = function (branchName, then) {
return this._run(['checkout', '-b', branchName], function (err, data) {
then && then(err, !err && this._parseCheckout(data));
});
};
/**
* Check out a tag or revision
*
* @param {string} what
* @param {Function} [then]
*/
Git.prototype.checkout = function (what, then) {
return this._run(['checkout', what], function (err, data) {
then && then(err, !err && this._parseCheckout(data));
});
};
/**
* Add a submodule
*
* @param {String} repo
* @param {String} path
* @param {Function} [then]
*/
Git.prototype.submoduleAdd = function (repo, path, then) {
return this._run(['submodule', 'add', repo, path], function (err) {
then && then(err);
});
};
/**
* 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._run(['checkout', '-b', branchName, startPoint], function (err, data) {
then && then(err, !err && this._parseCheckout(data));
});
};
/**
* List remote
*
* @param {String[]} [args]
* @param {Function} [then]
*/
Git.prototype.listRemote = function (args, then) {
var next = Git.trailingFunctionArgument(arguments);
var data = next === args || args === undefined ? [] : args;
/**
* Check out a local branch
*
* @param {string} branchName of branch
* @param {Function} [then]
*/
Git.prototype.checkoutLocalBranch = function (branchName, then) {
return this._run(['checkout', '-b', branchName], function (err, data) {
then && then(err, !err && this._parseCheckout(data));
});
};
if (typeof data === 'string') {
this._getLog('warn', 'Git#listRemote: args should be supplied as an array of individual arguments');
}
/**
* Add a submodule
*
* @param {string} repo
* @param {string} path
* @param {Function} [then]
*/
Git.prototype.submoduleAdd = function (repo, path, then) {
return this._run(['submodule', 'add', repo, path], function (err) {
then && then(err);
});
};
return this._run(['ls-remote'].concat(data), function (err, data) {
next && next(err, data);
});
};
/**
* List remote
*
* @param {string[]} [args]
* @param {Function} [then]
*/
Git.prototype.listRemote = function (args, then) {
var next = Git.trailingFunctionArgument(arguments);
var data = next === args || args === undefined ? [] : args;
/**
* Adds a remote to the list of remotes.
*
* @param {String} remoteName Name of the repository - eg "upstream"
* @param {String} remoteRepo Fully qualified SSH or HTTP(S) path to the remote repo
* @param {Function} [then]
* @returns {*}
*/
Git.prototype.addRemote = function (remoteName, remoteRepo, then) {
return this._run(['remote', 'add', remoteName, remoteRepo], function (err) {
then && then(err);
});
};
if (typeof data === 'string') {
this._getLog('warn', 'Git#listRemote: args should be supplied as an array of individual arguments');
}
/**
* Removes an entry from the list of remotes.
*
* @param {String} remoteName Name of the repository - eg "upstream"
* @param {Function} [then]
* @returns {*}
*/
Git.prototype.removeRemote = function (remoteName, then) {
return this._run(['remote', 'remove', remoteName], function (err) {
then && then(err);
});
};
return this._run(['ls-remote'].concat(data), function (err, data) {
next && next(err, data);
});
};
/**
* Gets the currently available remotes, setting the optional verbose argument to true includes additional
* detail on the remotes themselves.
*
* @param {boolean} [verbose=false]
* @param {Function} [then]
*/
Git.prototype.getRemotes = function (verbose, then) {
var next = Git.trailingFunctionArgument(arguments);
var args = verbose === true ? ['-v'] : [];
/**
* Adds a remote to the list of remotes.
*
* @param {string} remoteName Name of the repository - eg "upstream"
* @param {string} remoteRepo Fully qualified SSH or HTTP(S) path to the remote repo
* @param {Function} [then]
* @returns {*}
*/
Git.prototype.addRemote = function (remoteName, remoteRepo, then) {
return this._run(['remote', 'add', remoteName, remoteRepo], function (err) {
then && then(err);
});
};
return this.remote(args, function (err, data) {
next(err, !err && function () {
return data.trim().split('\n').reduce(function (remotes, remote) {
var detail = remote.trim().split(/\s+/);
var name = detail.shift();
/**
* Removes an entry from the list of remotes.
*
* @param {string} remoteName Name of the repository - eg "upstream"
* @param {Function} [then]
* @returns {*}
*/
Git.prototype.removeRemote = function (remoteName, then) {
return this._run(['remote', 'remove', remoteName], function (err) {
then && then(err);
});
};
if (!remotes[name]) {
remotes[name] = remotes[remotes.length] = {
name: name,
refs: {}
};
}
/**
* Gets the currently available remotes, setting the optional verbose argument to true includes additional
* detail on the remotes themselves.
*
* @param {boolean} [verbose=false]
* @param {Function} [then]
*/
Git.prototype.getRemotes = function (verbose, then) {
var next = Git.trailingFunctionArgument(arguments);
var args = verbose === true ? ['-v'] : [];
if (detail.length) {
remotes[name].refs[detail.pop().replace(/[^a-z]/g, '')] = detail.pop();
}
return this.remote(args, function (err, data) {
next(err, !err && function () {
return data.trim().split('\n').reduce(function (remotes, remote) {
var detail = remote.trim().split(/\s+/);
var name = detail.shift();
return remotes;
}, []).slice(0);
}());
});
};
if (!remotes[name]) {
remotes[name] = remotes[remotes.length] = {
name: name,
refs: {}
};
}
/**
* 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) {
if (!Array.isArray(options)) {
return this.then(function () {
then && then(new TypeError("Git.remote requires an array of arguments"));
});
}
if (detail.length) {
remotes[name].refs[detail.pop().replace(/[^a-z]/g, '')] = detail.pop();
}
if (options[0] !== 'remote') {
options.unshift('remote');
}
return remotes;
}, []).slice(0);
}());
});
};
return this._run(options, function (err, data) {
then && then(err || null, err ? null : data);
});
};
/**
* 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) {
if (!Array.isArray(options)) {
return this.then(function () {
then && then(new TypeError("Git.remote requires an array of arguments"));
});
}
/**
* Pushes the current committed changes to a remote, optionally specify the names of the remote and branch to use
* when pushing.
*
* @param {String} [remote]
* @param {String} [branch]
* @param {Function} [then]
*/
Git.prototype.push = function (remote, branch, then) {
var command = ["push"];
if (typeof remote === 'string' && typeof branch === 'string') {
command.push(remote, branch);
}
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
if (options[0] !== 'remote') {
options.unshift('remote');
}
return this._run(command, function (err, data) {
then && then(err, !err && data);
});
};
return this._run(options, function (err, data) {
then && then(err || null, err ? null : data);
});
};
/**
* 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) {
var command = ['push'];
if (typeof remote === "string") {
command.push(remote);
}
command.push('--tags');
/**
* 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) {
if (!Array.isArray(options)) {
return this.then(function () {
then && then(new TypeError("Git.tag requires an array of arguments"));
});
}
then = typeof arguments[arguments.length - 1] === "function" ? arguments[arguments.length - 1] : null;
if (options[0] !== 'tag') {
options.unshift('tag');
}
return this._run(command, function (err, data) {
then && then(err, !err && data);
});
};
return this._run(options, function (err, data) {
then && then(err || null, err ? null : data);
});
};
/**
* 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);
};
/**
* Pushes the current committed changes to a remote, optionally specify the names of the remote and branch to use
* when pushing.
*
* @param {string} [remote]
* @param {string} [branch]
* @param {Function} [then]
*/
Git.prototype.push = function (remote, branch, then) {
var command = ["push"];
if (typeof remote === 'string' && typeof branch === 'string') {
command.push(remote, branch);
}
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
/**
* 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);
};
return this._run(command, function (err, data) {
then && then(err, !err && data);
});
};
/**
* Return repository changes.
*
* @param {String} [options]
* @param {Function} [then]
*/
Git.prototype.diff = function (options, then) {
var command = ['diff'];
/**
* 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) {
var command = ['push'];
if (typeof remote === "string") {
command.push(remote);
}
command.push('--tags');
if (typeof options === 'string') {
command[0] += ' ' + options;
this._getLog('warn',
'Git#diff: supplying options as a single string is now deprecated, switch to an array of strings');
}
else if (Array.isArray(options)) {
command.push.apply(command, options);
}
then = typeof arguments[arguments.length - 1] === "function" ? arguments[arguments.length - 1] : null;
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
return this._run(command, function (err, data) {
then && then(err, !err && data);
});
};
return this._run(command, function (err, data) {
then && then(err, data);
});
};
/**
* 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);
};
/**
* rev-parse.
*
* @param {String|String[]} [options]
* @param {Function} [then]
*/
Git.prototype.revparse = function(options, then) {
var command = ['rev-parse'];
/**
* 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);
};
if (typeof options === 'string') {
command = command + ' ' + options;
this._getLog('warn',
'Git#revparse: supplying options as a single string is now deprecated, switch to an array of strings');
}
else if (Array.isArray(options)) {
command.push.apply(command, options);
}
/**
* Return repository changes.
*
* @param {string} [options]
* @param {Function} [then]
*/
Git.prototype.diff = function (options, then) {
var command = ['diff'];
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
if (typeof options === 'string') {
command[0] += ' ' + options;
this._getLog('warn',
'Git#diff: supplying options as a single string is now deprecated, switch to an array of strings');
}
else if (Array.isArray(options)) {
command.push.apply(command, options);
}
return this._run(command, function(err, data) {
then && then(err, data);
});
};
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
/**
* 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) {
var args = [].slice.call(arguments, 0);
var handler = typeof args[args.length - 1] === "function" ? args.pop() : null;
var command = ['show'];
if (typeof options === 'string') {
command = command + ' ' + options;
this._getLog('warn',
'Git#show: supplying options as a single string is now deprecated, switch to an array of strings');
}
else if (Array.isArray(options)) {
command.push.apply(command, options);
}
return this._run(command, function (err, data) {
then && then(err, data);
});
};
return this._run(command, function(err, data) {
handler && handler(err, !err && data);
});
};
/**
* rev-parse.
*
* @param {string|string[]} [options]
* @param {Function} [then]
*/
Git.prototype.revparse = function (options, then) {
var command = ['rev-parse'];
/**
* Call a simple function
* @param {Function} [then]
*/
Git.prototype.then = function (then) {
this._run([], function () {
typeof then === 'function' && then();
});
return this;
};
if (typeof options === 'string') {
command = command + ' ' + options;
this._getLog('warn',
'Git#revparse: supplying options as a single string is now deprecated, switch to an array of strings');
}
else if (Array.isArray(options)) {
command.push.apply(command, options);
}
/**
* Show commit logs.
*
* @param {Object} [options]
* @param {string} [options.from] The first commit to include
* @param {string} [options.to] The most recent commit to include
* @param {string} [options.file] A single file to include in the result
*
* @param {Function} [then]
*/
Git.prototype.log = function (options, then) {
var command = ["log", "--pretty=format:'%H;%ai;%s%d;%aN;%ae'"];
var opt = {};
if (typeof arguments[arguments.length - 1] === 'function') {
then = arguments[arguments.length - 1];
}
var args = [].slice.call(arguments, 0);
var handler = typeof args[args.length - 1] === "function" ? args.pop() : null;
return this._run(command, function (err, data) {
then && then(err, data);
});
};
if (!args.length) {
opt = {};
}
else if (typeof args[0] === "object") {
opt = args[0];
}
else if (typeof args[0] === "string" || typeof args[1] === "string") {
this._getLog('warn',
'Git#log: supplying to or from as strings is now deprecated, switch to an options configuration object');
opt = {
from: args[0],
to: args[1]
};
}
/**
* 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) {
var args = [].slice.call(arguments, 0);
var handler = typeof args[args.length - 1] === "function" ? args.pop() : null;
var command = ['show'];
if (typeof options === 'string') {
command = command + ' ' + options;
this._getLog('warn',
'Git#show: supplying options as a single string is now deprecated, switch to an array of strings');
}
else if (Array.isArray(options)) {
command.push.apply(command, options);
}
if (opt.from && opt.to) {
command.push(opt.from + "..." + opt.to);
}
return this._run(command, function (err, data) {
handler && handler(err, !err && data);
});
};
if (opt.file) {
command.push("--follow", options.file);
}
/**
* Call a simple function
* @param {Function} [then]
*/
Git.prototype.then = function (then) {
this._run([], function () {
typeof then === 'function' && then();
});
return this;
};
if (opt.n || opt['max-count']) {
command.push("--max-count=" + (opt.n || opt['max-count']));
}
/**
* Show commit logs.
*
* @param {Object} [options]
* @param {string} [options.from] The first commit to include
* @param {string} [options.to] The most recent commit to include
* @param {string} [options.file] A single file to include in the result
*
* @param {Function} [then]
*/
Git.prototype.log = function (options, then) {
var command = ["log", "--pretty=format:'%H;%ai;%s%d;%aN;%ae'"];
var opt = {};
return this._run(command, function (err, data) {
handler && handler(err, !err && this._parseListLog(data));
});
};
var args = [].slice.call(arguments, 0);
var handler = typeof args[args.length - 1] === "function" ? args.pop() : null;
Git.prototype._rm = function (files, options, then) {
return this._run(['rm', options, [].concat(files)], function (err) {
then && then(err);
});
};
if (!args.length) {
opt = {};
}
else if (typeof args[0] === "object") {
opt = args[0];
}
else if (typeof args[0] === "string" || typeof args[1] === "string") {
this._getLog('warn',
'Git#log: supplying to or from as strings is now deprecated, switch to an options configuration object');
opt = {
from: args[0],
to: args[1]
};
}
Git.prototype._parsePull = function (pull) {
var changes = {
files: [],
insertions: {},
deletions: {},
summary: {
changes: 0,
insertions: 0,
deletions: 0
}
};
if (opt.from && opt.to) {
command.push(opt.from + "..." + opt.to);
}
var fileUpdateRegex = /^\s*(.+)\s\|\s(\d+)\s([\+]+)/;
for (var lines = pull.split('\n'), i = 0, l = lines.length; i < l; i++) {
var update = fileUpdateRegex.exec(lines[i]);
if (opt.file) {
command.push("--follow", options.file);
}
// search for update statement for each file
if (update) {
changes.files.push(update[1]);
if (opt.n || opt['max-count']) {
command.push("--max-count=" + (opt.n || opt['max-count']));
}
var insertions = update[3].length;
if (insertions) {
changes.insertions[update[1]] = insertions;
}
if (update[2] > insertions) {
changes.deletions[update[1]] = update[2] - insertions;
}
}
return this._run(command, function (err, data) {
handler && handler(err, !err && this._parseListLog(data));
});
};
// summary appears after updates
else if (changes.files.length && (update = /(\d+)\D+(\d+)\D+(\d+)/.exec(lines[i]))) {
changes.summary.changes = +update[1];
changes.summary.insertions = +update[2];
changes.summary.deletions = +update[3];
}
}
Git.prototype._rm = function (files, options, then) {
return this._run(['rm', options, [].concat(files)], function (err) {
then && then(err);
});
};
return changes;
};
Git.prototype._parsePull = function (pull) {
var changes = {
files: [],
insertions: {},
deletions: {},
summary: {
changes: 0,
insertions: 0,
deletions: 0
}
};
Git.prototype._parseListTags = function (tags) {
var tagList = tags.split('\n').sort(function (tagA, tagB) {
var partsA = tagA.split('.');
var partsB = tagB.split('.');
var fileUpdateRegex = /^\s*(.+)\s\|\s(\d+)\s([\+]+)/;
for (var lines = pull.split('\n'), i = 0, l = lines.length; i < l; i++) {
var update = fileUpdateRegex.exec(lines[i]);
for (var i = 0, l = Math.max(partsA.length, partsB.length); i < l; i++) {
var diff = partsA[i] - partsB[i];
if (diff) {
return diff > 0 ? 1 : -1;
}
// search for update statement for each file
if (update) {
changes.files.push(update[1]);
var insertions = update[3].length;
if (insertions) {
changes.insertions[update[1]] = insertions;
}
if (update[2] > insertions) {
changes.deletions[update[1]] = update[2] - insertions;
}
}
return 0;
});
// summary appears after updates
else if (changes.files.length && (update = /(\d+)\D+(\d+)\D+(\d+)/.exec(lines[i]))) {
changes.summary.changes = +update[1];
changes.summary.insertions = +update[2];
changes.summary.deletions = +update[3];
}
}
return {
latest: tagList.length && tagList[tagList.length - 1],
all: tagList
};
};
return changes;
};
Git.prototype._parseStatus = function (status) {
var line;
var lines = status.trim().split('\n');
Git.prototype._parseListTags = function (tags) {
var tagList = tags.split('\n').sort(function (tagA, tagB) {
var partsA = tagA.split('.');
var partsB = tagB.split('.');
var not_added = [];
var deleted = [];
var modified = [];
var created = [];
for (var i = 0, l = Math.max(partsA.length, partsB.length); i < l; i++) {
var diff = partsA[i] - partsB[i];
if (diff) {
return diff > 0 ? 1 : -1;
}
}
var whitespace = /\s+/;
return 0;
});
while (line = lines.shift()) {
line = line.trim().split(whitespace);
return {
latest: tagList.length && tagList[tagList.length - 1],
all: tagList
};
};
switch (line.shift()) {
case "??":
not_added.push(line.join());
break;
case "D":
deleted.push(line.join());
break;
case "M":
modified.push(line.join());
break;
case "A":
case "AM":
created.push(line.join());
break;
}
}
Git.prototype._parseStatus = function (status) {
var line;
var lines = status.trim().split('\n');
return {
not_added: not_added,
deleted: deleted,
modified: modified,
created: created
};
};
var not_added = [];
var deleted = [];
var modified = [];
var created = [];
Git.prototype._parseCheckout = function (checkout) {
// TODO
};
var whitespace = /\s+/;
Git.prototype._parseFetch = function (fetch) {
return fetch;
};
while (line = lines.shift()) {
line = line.trim().split(whitespace);
Git.prototype._parseListLog = function (logs) {
var logList = logs.split('\n').map(function (item) {
var parts = item.split(';');
switch (line.shift()) {
case "??":
not_added.push(line.join());
break;
case "D":
deleted.push(line.join());
break;
case "M":
modified.push(line.join());
break;
case "A":
case "AM":
created.push(line.join());
break;
}
}
return {
hash: parts[0],
date: parts[1],
message: parts[2],
author_name: parts[3],
author_email: parts[4]
}
});
return {
not_added: not_added,
deleted: deleted,
modified: modified,
created: created
};
};
return {
latest: logList.length && logList[logList.length - 1],
total: logList.length,
all: logList
};
};
Git.prototype._parseCheckout = function (checkout) {
// TODO
};
/**
* Schedules the supplied command to be run, the command should not include the name of the git binary and should
* either be a string, or an array where the first argument is a formatted string accepted by `format` in the util
* module that uses the other entities in the array as the template data.
*
* @param {string|string[]} command
* @param {Function} [then]
* @see http://nodejs.org/api/util.html#util_util_format_format
* @returns {Git}
*/
Git.prototype._run = function (command, then) {
if (typeof command === "string") {
command = command.split(" ");
}
this._runCache.push([command, then]);
this._schedule();
Git.prototype._parseFetch = function (fetch) {
return fetch;
};
return this;
};
Git.prototype._parseListLog = function (logs) {
var logList = logs.split('\n').map(function (item) {
var parts = item.split(';');
Git.prototype._schedule = function () {
if (!this._childProcess && this._runCache.length) {
var Buffer = this.Buffer;
var task = this._runCache.shift();
var command = task[0];
var then = task[1];
return {
hash: parts[0],
date: parts[1],
message: parts[2],
author_name: parts[3],
author_email: parts[4]
}
});
var stdOut = [];
var stdErr = [];
var spawned = this.ChildProcess.spawn(this._command, command.slice(0), {
cwd: this._baseDir
});
return {
latest: logList.length && logList[logList.length - 1],
total: logList.length,
all: logList
};
};
spawned.stdout.on('data', function (buffer) { stdOut.push(buffer); });
spawned.stderr.on('data', function (buffer) { stdErr.push(buffer); });
/**
* 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]
*
* @returns {Git}
*/
Git.prototype._run = function (command, then) {
if (typeof command === "string") {
command = command.split(" ");
}
this._runCache.push([command, then]);
this._schedule();
spawned.on('close', function (exitCode, exitSignal) {
delete this._childProcess;
return this;
};
if (exitCode && stdErr.length) {
stdErr = Buffer.concat(stdErr).toString('utf-8');
Git.prototype._schedule = function () {
if (!this._childProcess && this._runCache.length) {
var Buffer = this.Buffer;
var task = this._runCache.shift();
var command = task[0];
var then = task[1];
this._getLog('error', stdErr);
this._runCache = [];
then.call(this, stdErr, null);
}
else {
then.call(this, null, Buffer.concat(stdOut).toString('utf-8'));
}
var stdOut = [];
var stdErr = [];
var spawned = this.ChildProcess.spawn(this._command, command.slice(0), {
cwd: this._baseDir
});
process.nextTick(this._schedule.bind(this));
}.bind(this));
spawned.stdout.on('data', function (buffer) {
stdOut.push(buffer);
});
spawned.stderr.on('data', function (buffer) {
stdErr.push(buffer);
});
this._childProcess = spawned;
spawned.on('close', function (exitCode, exitSignal) {
delete this._childProcess;
if (this._outputHandler) {
this._outputHandler(command[0],
this._childProcess.stdout,
this._childProcess.stderr);
if (exitCode && stdErr.length) {
stdErr = Buffer.concat(stdErr).toString('utf-8');
this._getLog('error', stdErr);
this._runCache = [];
then.call(this, stdErr, null);
}
}
};
else {
then.call(this, null, Buffer.concat(stdOut).toString('utf-8'));
}
/**
* Given any number of arguments, returns the last argument if it is a function, otherwise returns null.
* @returns {Function|null}
*/
Git.trailingFunctionArgument = function (args) {
var trailing = args[args.length - 1];
return (typeof trailing === "function") ? trailing : null;
};
process.nextTick(this._schedule.bind(this));
}.bind(this));
module.exports = Git;
this._childProcess = spawned;
if (this._outputHandler) {
this._outputHandler(command[0],
this._childProcess.stdout,
this._childProcess.stderr);
}
}
};
/**
* Given any number of arguments, returns the last argument if it is a function, otherwise returns null.
* @returns {Function|null}
*/
Git.trailingFunctionArgument = function (args) {
var trailing = args[args.length - 1];
return (typeof trailing === "function") ? trailing : null;
};
module.exports = Git;
}());
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc