Skip to content

Instantly share code, notes, and snippets.

@hellatan
Last active August 29, 2015 14:03
Show Gist options
  • Save hellatan/c1d042e2a26f0e17ef21 to your computer and use it in GitHub Desktop.
Save hellatan/c1d042e2a26f0e17ef21 to your computer and use it in GitHub Desktop.
Delete remote branches (typical context is github for me)
#!/usr/bin/env node
//DO NOT PUT "use strict" HERE OR THE LOGGER WILL NOT BE ABLE TO LOG ERROR
/*
1. node.js must be installed
2. added +x to this script
3. put this script anywhere, but run the shell command from within the desired repository
*/
/**
* @var {Array} branches to delete from the github remote
* a uri to a json file can be passed in as
* the `--list` argument: --list=./branches.json
*/
var branches = [];
var missingBranches = [];
var ogBranchLength = 0;
var numErrBranches = 0;
var cpBranches;
var fs = require('fs');
var util = require('util');
var sys = require('sys');
var exec = require('child_process').exec;
// for terminal input
var readline = require('readline');
var rl = readline.createInterface(process.stdin, process.stdout);
var cwd = process.cwd();
var UNIX_ERROR_LOG_ROOT = cwd + '/logs';
var DELETE_LOCAL_BRANCH_VALUE = 'Y';
var logFile = UNIX_ERROR_LOG_ROOT + "/branches_delete.log";
util.log('Deleting branches from Github');
function logDivider() {
if (branches.length) {
console.log('');
console.log('------------------');
console.log('');
}
}
//Test or create the directory, we do it synchronously to never loose any log message
function delBranches(answer) {
if (branches.length) {
var branch = branches.shift();
util.log('deleting ' + branch + ' from origin');
exec('git push origin :' + branch, function (err, stdout, stderr) {
if (stderr) {
/*
// TODO: write to log file
try{
if (!fs.statSync(unix_error_log_root).isDirectory()){
fs.mkdirSync(unix_error_log_root, 0600);
}
}catch(e){
fs.mkdirSync(unix_error_log_root, 0600);
}
if (!fs.existsSync(logFile)) {
fs.writeFileSync(logFile);
}
stderr = fs.createWriteStream(logFile, { flags: 'a' });
*/
// if the branch isn't present on the remote
// an error will be output
util.log(stderr);
numErrBranches++;
missingBranches.push(branch);
}
if (answer === DELETE_LOCAL_BRANCH_VALUE) {
delLocalBranch(branch, answer, delBranches);
} else {
delBranches(answer);
logDivider();
}
});
} else {
util.log('there are no branches to delete');
util.log('total branches deleted: ' + (ogBranchLength - numErrBranches));
if (numErrBranches) {
util.log('missing branches: ' + numErrBranches);
util.log('branches missing: \n' + missingBranches.join('\n'));
}
// process.exit(0);
pruneLocal();
}
}
function delLocalBranch(branch, answer, cb) {
util.log('deleting ' + branch + ' locally');
exec('git branch -d ' + branch, function (err, stdout, stderr) {
if (stderr) {
// if the branch isn't present
// an error will be output
util.log(stderr);
if (answer === null) {
// came from localOnly
numErrBranches++;
missingBranches.push(branch);
}
}
logDivider();
if (cb) {
cb(answer);
}
});
}
function delLocalBranchOnly() {
if (branches.length) {
delLocalBranch(branches.shift(), null, delLocalBranchOnly);
} else {
util.log('total branches deleted: ' + (ogBranchLength - numErrBranches));
if (numErrBranches) {
util.log('missing branches: ' + numErrBranches);
util.log('branches missing: \n' + missingBranches.join('\n'));
}
process.exit(0);
}
}
function startUpLocal() {
ogBranchLength = branches.length;
delLocalBranchOnly();
}
function startUp() {
ogBranchLength = branches.length;
rl.question('Delete local branches: [Yn] ', function (answer) {
if (!answer) {
startUp();
return;
}
if (answer === DELETE_LOCAL_BRANCH_VALUE) {
util.log('Branches will be deleted locally');
}
delBranches(answer);
});
}
function pruneLocal() {
rl.question('Prune local repo of stale branches: [Yn] ', function (answer) {
if (!answer) {
pruneLocal();
return;
}
if (answer === DELETE_LOCAL_BRANCH_VALUE) {
exec('git remote prune origin', function (err, stdout, stderr) {
if (stderr) {
util.log(stderr);
}
console.log('local repo has been pruned of stale branches');
console.log('good bye');
process.exit(0);
});
} else {
console.log('no pruning took place');
process.exit(0);
}
rl.close();
});
}
var args = process.argv.slice(2);
var localOnly;
if (args.length) {
localOnly = args.indexOf('--localOnly') > -1;
args.forEach(function (val, index, array) {
if (val.indexOf('--list') > -1 && val.indexOf('=') > -1) {
var list = val.split('=');
var file = list[1];
fs.readFile(file, 'utf8', function (err, data) {
if (err) {
throw err;
}
data = JSON.parse(data);
if (!data.branches) {
util.log('missing `branches`<array> property of list of branches');
util.log('exiting process');
process.exit(0);
}
branches = data.branches;
cpBranches = data.branches;
if (localOnly) {
startUpLocal();
} else {
startUp();
}
});
}
});
} else {
if (!branches.length) {
util.log('you must have at least one branch to delete.');
util.log('exiting process');
process.exit(0);
}
startUp();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment