ogit
Version:
A lazy developer's Git CLI made simple. Makes using git on cloud IDEs (i.e. C9) a walk in the park.
948 lines (947 loc) • 38.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const GitStatus_1 = require("../models/GitStatus");
const SimpleGit = require("simple-git/promise");
const json_object_mapper_1 = require("json-object-mapper");
const cli_ux_1 = require("cli-ux");
const models_1 = require("../models");
const GitStash_1 = require("../models/GitStash");
const keygen = require('@andrewwlane/ssh-keygen2');
/**
* Wrapper class for git commands.
*
* @export
* @class GitFacade
*/
var GitFacade;
(function (GitFacade) {
GitFacade.git = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let relativePath;
try {
relativePath = yield SimpleGit().raw(['rev-parse', '--show-cdup']);
}
catch (error) {
throw new Error(`Call to get repository directory failed with message: ${error.message}`);
}
//refactor
if (!relativePath.trim()) {
relativePath = '.';
}
else {
relativePath = relativePath.trim();
}
// console.log(`relativePath ${relativePath}`);
const g = SimpleGit();
g.cwd(relativePath);
return g;
});
/**
* Returns the status of the current git repo.
*
* @static
* @memberof GitFacade
*/
GitFacade.status = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let statusObj;
try {
const gitStatus = yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.status(); }));
statusObj = json_object_mapper_1.ObjectMapper.deserialize(GitStatus_1.GitStatus, gitStatus);
}
catch (error) {
throw new Error(`Call to get repository status failed with message: ${error.message}`);
}
return statusObj;
});
/**
* Returns the remote origin url for this branch.
*
* @static
* @memberof GitFacade
*/
GitFacade.originUrl = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let url;
try {
url = yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['config', '--get', 'remote.origin.url']); }));
}
catch (error) {
throw new Error(`Call to get remote origin failed with message: ${error.message}`);
}
return url ? url.trim() : undefined;
});
/**
* Initializes the current directory as a git repo if not already.
*
* @static
* @memberof GitFacade
*/
GitFacade.initialize = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let success = false;
try {
cli_ux_1.default.action.start('Initializing git repo');
if (!(yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.checkIsRepo(); })))) {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.init(); }));
success = true;
cli_ux_1.default.action.stop();
}
else {
cli_ux_1.default.action.stop('Skipping initialization as the directiory is already a git repo!');
}
}
catch (error) {
throw new Error(`Call to check init status failed with message: ${error.message}`);
}
return success;
});
/**
* Sets up the git project from in the current directory. Works the same as
* cloning except that cloning requires a new directory be created and
* the code checked out in that.
*
* By default, this operation will pull the master branch.
*
* TODO: How to test this method?
*
* @static
* @memberof GitFacade
*/
GitFacade.checkoutRepo = (url) => tslib_1.__awaiter(this, void 0, void 0, function* () {
let success = false;
const branch = 'master';
yield GitFacade.initialize();
try {
cli_ux_1.default.action.start('Adding remote origin to ' + url, '', { stdout: false });
const originUrl = yield GitFacade.originUrl();
if (originUrl) {
cli_ux_1.default.action.stop('failed as remote origin already exists!');
}
else {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.addRemote('origin', url); }));
success = true;
cli_ux_1.default.action.stop();
}
}
catch (error) {
cli_ux_1.default.action.stop(`Call to setup git repo failed with message: ${error.message}`);
}
if (success) {
try {
cli_ux_1.default.action.start('Pulling down repository');
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.pull('origin', branch); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop(`Pulling down branch failed with message: ${error.message}`);
}
}
});
/**
* Returns the list of branches in the current repo.
*
* @static
* @memberof GitFacade
*/
GitFacade.listBranches = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const branches = [];
const remoteBranchesSummary = json_object_mapper_1.ObjectMapper.deserialize(models_1.GitBranchSummary, yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.branch(['-r']); })));
remoteBranchesSummary.branches.forEach(branch => {
branch.isLocal = false;
branches.push(branch);
});
const localBranchesSummary = json_object_mapper_1.ObjectMapper.deserialize(models_1.GitBranchSummary, yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.branchLocal(); })));
localBranchesSummary.branches.forEach(branch => {
branch.isLocal = true;
branches.push(branch);
});
return branches;
});
/**
* Commits the files into repo.
*/
GitFacade.commit = (message, fileNames, skipValidation) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const options = { '--include': true };
if (skipValidation) {
options['--no-verify'] = null;
}
try {
cli_ux_1.default.action.start('Committing changes');
const commitResult = yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.commit(message, fileNames, options); }));
cli_ux_1.default.action.stop();
return commitResult;
}
catch (error) {
throw new Error(`Call to commit changes failed with message: ${error.message}`);
}
});
/**
* Pushes the local commits to the remote branch
* @param branchName the remote branch name
*/
GitFacade.push = (branchNames) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Pushing changes to remote ${branchNames.join(', ')}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.push('origin', ...branchNames); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw new Error(`Call to push changes failed with message: ${error.message}`);
}
});
/**
* Add the file to source control.
*
* @static
* @memberof GitFacade
*/
GitFacade.addToRepo = (filePath) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Adding file to repo ${filePath} `);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.add(filePath); }));
cli_ux_1.default.action.stop();
}
catch (error) {
throw new Error(`Call to add file to repo failed with message: ${error.message}`);
}
});
/**
* Optimizes the repo by calling garbage collection
*/
GitFacade.optimizeRepo = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['gc']); }));
});
/**
* Ammends the last commit
*
* @static
* @memberof GitFacade
*/
GitFacade.ammendLastCommit = (filePaths, message) => tslib_1.__awaiter(this, void 0, void 0, function* () {
let summary;
cli_ux_1.default.action.start(`Updating last comment to ${message}`);
summary = yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield g.commit(message, filePaths, {
'--amend': null
});
}));
cli_ux_1.default.action.stop();
return summary;
});
/**
* Returns the last commit message from the commits
*
* @static
* @memberof GitFacade
*/
GitFacade.getLastCommitMessage = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
return (yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['log', '--pretty=format:"%s"', '-n 1']); }))).replace(/['"]+/g, '');
});
/**
* Return file names in an string array from the last commit
*
* @static
* @memberof GitFacade
*/
GitFacade.getFileNamesFromCommit = (commitHash) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const fileNamesString = yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield g.raw([
'diff-tree',
'--no-commit-id',
'--name-only',
'-r',
commitHash
]);
}));
return fileNamesString
? fileNamesString
.split('\n')
.filter(n => n)
.sort()
: [];
});
/**
* Returns the last commit hash from the commits
*
* @static
* @memberof GitFacade
*/
GitFacade.getLastCommitHash = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
return (yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['log', '--pretty=format:"%h"', '-n 1']); }))).replace(/['"]+/g, '');
});
/**
* Returns the commit message by looking up the hash in repo
*
* @static
* @memberof GitFacade
*/
GitFacade.getMessageFromCommitHash = (hash) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return SimpleGit().raw(['log', '--pretty=format:%s', '-n 1', hash]);
});
/**
* Reverts a commit using the commit hash. It does not delete the files
*
* @static
* @memberof GitFacade
*/
GitFacade.revertCommit = (hash) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const commitMessage = yield GitFacade.getMessageFromCommitHash(hash);
cli_ux_1.default.action.start(`Reverting commit ${hash} with subject ${commitMessage}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['reset', '--soft', `${hash}~`]); }));
cli_ux_1.default.action.stop();
});
/**
* Reverts a commit using the commit hash. It does not delete the files
*
* @static
* @memberof GitFacade
*/
GitFacade.deleteCommit = (hash) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const commitMessage = yield GitFacade.getMessageFromCommitHash(hash);
cli_ux_1.default.action.start(`Deleting commit ${hash} with subject ${commitMessage}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['reset', '--hard', `${hash}~`]); }));
cli_ux_1.default.action.stop();
});
/**
* Creates a local branch from a remote branch
*
* @static
* @memberof GitFacade
*/
GitFacade.createBranch = (branchName, remoteBranchName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start(`Creating a local branch ${branchName}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.checkout(['-b', branchName, '--track', remoteBranchName]); }));
cli_ux_1.default.action.stop();
});
/**
* Renames a local branch
*
* @static
* @memberof GitFacade
*/
GitFacade.renameBranch = (currantName, newName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Renaming local branch ${currantName} to ${newName}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['branch', '-m', currantName, newName]); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw new Error(`Call to rename branch failed with message: ${error.message}`);
}
});
/**
* Switches to the local branch
* TODO: missing unit test...
*
* @static
* @memberof GitFacade
*/
GitFacade.switchBranch = (branchName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start(`Switching to branch ${branchName}`);
try {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.checkout(branchName); }));
cli_ux_1.default.action.stop();
}
catch (err) {
cli_ux_1.default.action.stop('failed');
const errorRegex = /checkout:\n((.+\n)+)Please/;
const fileNames = errorRegex.exec(err.message)[1].trim();
err.fileNamesArray = fileNames.split('\n').sort();
throw err;
}
});
/**
* Returns the current branch name
*
* @static
* @memberof GitFacade
*/
GitFacade.getCurrentBranchName = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
return (yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['symbolic-ref', '--short', 'HEAD']); }))).trim();
});
/**
* Deletes a branch from local repo
*/
GitFacade.deleteLocalBranch = (branchName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start(`Deleting local branch ${branchName}`);
try {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['branch', '-D', branchName]); }));
cli_ux_1.default.action.stop();
}
catch (e) {
cli_ux_1.default.action.stop('failed');
throw e;
}
});
/**
* Deletes a remote branch
*/
GitFacade.deleteRemoteBranch = (branchName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start(`Deleting remote branch ${branchName}`);
try {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['push', 'origin', '--delete', branchName]); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Clears the stash by removing all entries
*
*/
GitFacade.clearStash = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start('Removing all stashed changes');
try {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield g.stash({
clear: null
});
}));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
*
*
* @param {number} stashNumber
* @returns {Promise<string[]>}
*/
/**
* Returns a list of file names contained in a stash
* @param stashNumber the stash number to lookup on
*/
const getStashedFiles = (stashNumber) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const fileNames = [];
//tracked portion
const fileNamesLookupOptions = {
show: null,
'--name-only': null
};
fileNamesLookupOptions[`stash@{${stashNumber}}`] = null;
const trackedFileNames = (yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.stash(fileNamesLookupOptions); })))
.split('\n')
.filter(n => n);
trackedFileNames.forEach(fileName => fileNames.push(fileName));
/**
* Untracked portion, can throw error if there is no untracked file in
* that particular stash
*/
// untrackedLookupOptions[`stash@{${stashNumber}}^3`] = null;
try {
const untrackedFileNames = (yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield g.raw([
'ls-tree',
'-r',
`stash@{${stashNumber}}^3`,
'--name-only'
]);
})))
.split('\n')
.filter(n => n);
untrackedFileNames.forEach(fileName => fileNames.push(fileName));
// tslint:disable-next-line
}
catch (_error) { }
return fileNames.sort();
});
/**
* Returns the list of stash names and the files attached to the stashes
*/
GitFacade.getStashes = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
const stashes = [];
const stashNames = (yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield g.stash({
list: null,
'--pretty': 'format:%s %N'
});
})))
.split('\n')
.filter(n => n);
for (let i = 0; i < stashNames.length; i++) {
const stashEntries = stashNames[i].split(':');
const stash = new GitStash_1.GitStash();
stash.stashNumber = i;
stash.branchName = stashEntries[0]
.split(' ')
.splice(-1)[0]
.trim();
stash.stashName = stashEntries[1].trim();
stash.files = yield getStashedFiles(i);
stashes.push(stash);
}
return stashes;
});
/**
* Deletes a stash based on the number supplied
* @param stashNumber Stash number to delete
*/
GitFacade.deleteStash = (stashNumber, message) => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start(`Deleting stash ${message}`);
const deleteStashCommandOptions = {
drop: null
};
deleteStashCommandOptions[`stash@{${stashNumber}}`] = null;
try {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.stash(deleteStashCommandOptions); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Removes a stash from local repo
*/
GitFacade.unstash = (stashNumber, message, remove = true) => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start(`Unstashing changes for ${message}`);
const unStashCommandOptions = [];
if (remove) {
unStashCommandOptions.push('pop');
}
else {
unStashCommandOptions.push('apply');
}
unStashCommandOptions[`stash@{${stashNumber}}`] = null;
try {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.stash(unStashCommandOptions); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
const errorRegex = /merge:\n((.+\n)+)Please/;
const fileNames = errorRegex.exec(error.message)[1].trim();
error.fileNamesArray = fileNames.split('\n').sort();
throw error;
}
});
/**
* Creates a new stash of the files
* @param message to add for the stash
* @param fileNames the list of file names
* @param partial is this a partial list or not
*/
GitFacade.stash = (message, fileNames, partial = true) => tslib_1.__awaiter(this, void 0, void 0, function* () {
cli_ux_1.default.action.start(`Stashing changes for ${message}`);
let commandList;
if (partial) {
commandList = ['stash', 'push', '-m', message, '--'];
for (let i = 0; i < fileNames.length; i++) {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.add(fileNames[i]); }));
commandList.push(fileNames[i]);
}
}
else {
commandList = ['stash', 'save', '-u', message];
}
try {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(commandList); }));
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Synchronises the remote branches
*/
GitFacade.syncRemoteBranches = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start('Resyncing remote branches');
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['fetch', 'origin', '--prune']); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Reverts the changes to a file.
* @param file the path to the file
*/
GitFacade.revertFile = (file) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Reverting file ${file.path}`);
if (file.changeType === GitStatus_1.ChangeTypes.New) {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['clean', '-f', file.path]); }));
}
else if (file.changeType === GitStatus_1.ChangeTypes.Added) {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['reset', file.path]); }));
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['clean', '-f', file.path]); }));
}
else {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.checkout(['--', file.path]); }));
}
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Returns a list of tag names for the repo
*/
GitFacade.tags = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let tags;
try {
cli_ux_1.default.action.start('Retrieving tag names');
tags = yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.tags(); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
return tags;
});
/**
* Resets the current repo.
*
* @param pointer tag or branch name to set HEAD to
* @param strategy strategy to take
*/
GitFacade.reset = (pointer, strategy) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Reseting current HEAD to ${pointer}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['reset', strategy, pointer]); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Returns the list of file names that have merge conflict.
*/
GitFacade.filesWithMergeConflicts = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
let fileNamesList;
try {
cli_ux_1.default.action.start('Retrieving file names with merge conflict');
const fileNames = yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.diff(['--name-only', '--diff-filter=U']); }));
fileNamesList = fileNames.split('\n').filter(n => n);
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
return fileNamesList;
});
/**
* Pulls the changes from the remote branch into current.
* @param branch the remote branch to pull changes from. Defaults to the origin branch
*/
GitFacade.pullRemoteChanges = (branch) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Pulling changes from ${branch ? branch : 'origin'}`);
const options = ['pull', '--no-stat', '-v', 'origin'];
if (branch) {
options.push(branch);
}
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(options); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Accept merge changes.
* @param acceptRemote should use remote or local changes
* @param filePath
*/
GitFacade.acceptChanges = (acceptRemote, filePath = '.') => tslib_1.__awaiter(this, void 0, void 0, function* () {
const commitMessage = `Accepting ${acceptRemote ? 'remote' : 'local'} changes for ${filePath !== '.' ? filePath : 'all conflicted files'}`;
try {
cli_ux_1.default.action.start(commitMessage);
const checkoutOptions = ['checkout'];
if (acceptRemote) {
checkoutOptions.push('--theirs');
}
else {
checkoutOptions.push('--ours');
}
checkoutOptions.push(filePath);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(checkoutOptions); }));
if (filePath === '.') {
yield GitFacade.autoCommit(commitMessage);
}
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
GitFacade.autoCommit = (message) => tslib_1.__awaiter(this, void 0, void 0, function* () {
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(['add', '--all']); }));
return SimpleGit().commit(message);
});
/**
* Cancels the merge operation.
*/
GitFacade.cancelMerge = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start('Cancelling merge attempt');
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.merge(['--abort']); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Merges the brnach into the current branch
* @param branchName the source branch to merge
*/
GitFacade.merge = (branchName, message = '') => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Merging branch ${branchName}`);
const mergeCommandParams = [];
if (message) {
mergeCommandParams.push('-m', message);
}
mergeCommandParams.push('--no-ff', branchName);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.merge(mergeCommandParams); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Sets the config value
* @param config the config to set
* @param value the value to set
* @param global if its global or not
*/
GitFacade.setConfig = (config, value, global) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const commands = ['config'];
if (global) {
commands.push('--global');
}
commands.push(config, value);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return g.raw(commands); }));
});
/**
* Returns the config value
* @param config to look for
* @param global if global config or not
*/
GitFacade.getConfig = (config, global) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const commands = ['config'];
if (global) {
commands.push('--global');
}
commands.push(config);
return yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.raw(commands); }));
});
/**
* Returns the config data
* @param config name of the config
* @param global lookup in global scope?
*/
GitFacade.getConfigData = (config, global = true) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Getting config ${config}`);
const data = yield GitFacade.getConfig(config, global);
cli_ux_1.default.action.stop();
return data ? data.trim() : null;
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Returns the config data by looking into local config first and then global config
* @param config name of the config
*/
GitFacade.getConfigDataFromAnyWhere = (config) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Getting config ${config}`);
let value = yield GitFacade.getConfig(config, false);
if (!value) {
value = yield GitFacade.getConfig(config, true);
}
return value ? value.trim() : null;
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Sets the config data
* @param config name of the config
* @param value value of the config
* @param global lookup in global scope?
*/
GitFacade.setConfigData = (config, value, global = true) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Setting config ${config}`);
yield GitFacade.setConfig(config, value, global);
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Generates SSH Key pairs.
* @param options
*/
GitFacade.generateSSHKeys = (options) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
cli_ux_1.default.action.start(`Generating SSH Keys ${options.location} `);
keygen(options, (err, pairs) => {
if (err) {
cli_ux_1.default.action.stop('failed');
reject(err);
}
else {
cli_ux_1.default.action.stop();
resolve(pairs);
}
});
});
});
/**
* Clones a remote repo into the directory
*
* @param url of the remote repo
* @param dirName to clone to
*/
GitFacade.cloneRepo = (url, dirName, reference) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Cloning repo ${url}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
return yield g.clone(url, dirName, reference ? ['--branch', reference] : null);
}));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
GitFacade.listRemoteReferences = (url) => tslib_1.__awaiter(this, void 0, void 0, function* () {
let references = [];
try {
cli_ux_1.default.action.start(`Getting references for ${url}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const referencesString = yield g.listRemote(['--heads', '--tags', url]);
referencesString
.split('\n')
.filter(v => !!v && v.indexOf('^{}') === -1)
.forEach(refStr => {
// console.log(refStr.split('\t'));
const chunks = refStr.split('\t');
if (chunks[1].indexOf('refs/') > -1) {
references.push({
hash: chunks[0],
name: chunks[1].replace('refs/', '')
});
}
});
// console.log(`referencesString - ${referencesString}`);
}));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
return references;
});
/**
* Adds a tag to the current repo. Only does annotated tagging.
* @param name the name of the tag
* @param message message for the tag
*/
GitFacade.addTag = (name, message) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const options = ['-a', name, '-m', message];
try {
cli_ux_1.default.action.start(`Tagging branch as ${name}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () {
yield g.tag(options);
}));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Pushes a tag to origin
* @param tagName the tag name to push
*/
GitFacade.pushTag = (tagName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Pushing tag ${tagName} to origin`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.push('origin', tagName); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Pushes all the tags to origin
* @param tagName the tag name to push
*/
GitFacade.pushAllTags = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start('Pushing all tags to origin');
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.push('origin', '--tags'); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Deletes the tag from local repo
*/
GitFacade.deleteLocalTag = (tagName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Deleting tag ${tagName}`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.tag(['-d', tagName]); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
/**
* Deletes the tag from remote repo
*/
GitFacade.deleteRemoteTag = (tagName) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
cli_ux_1.default.action.start(`Deleting tag ${tagName} from origin`);
yield GitFacade.git().then((g) => tslib_1.__awaiter(this, void 0, void 0, function* () { return yield g.push('origin', `:refs/tags/${tagName}`); }));
cli_ux_1.default.action.stop();
}
catch (error) {
cli_ux_1.default.action.stop('failed');
throw error;
}
});
})(GitFacade = exports.GitFacade || (exports.GitFacade = {}));