Skip to content

Instantly share code, notes, and snippets.

@iamtekeste
Last active May 8, 2017 13:17
This is a NodeJS script to clean up our remote git repository by deleting branches we longer need. I have commented out the line that does the actual deletion for the time being.
#!/usr/bin/env node
'use strict';
const fs = require('fs');
const readline = require('readline');
const execSync = require('child_process').execSync;
const config = {
filterText: 'DISCO-',
mergedBranches: `${process.env['HOME']}/merged_branches.txt`,
notMergedBranches: `${process.env['HOME']}/not_merged_branches.txt`,
notMergedOldBranches: `${process.env['HOME']}/not_merged_two_month_old_branches.txt`,
branchAge: '2 month ago'
};
/**
* @param {file} - path to file that contains lines of branch
* @return {string[]} An array of branches
*/
function fileToArray(file) {
try {
let branches = fs.readFileSync(file, 'utf-8').trim().split('\n');
return branches.map(branchName => branchName.trim());
} catch(err) {
throw err;
}
}
/**
* @param {branchName}
* @return {Boolean} - if branch is older than config.branchAge return true
*/
function branchIsOld(branchName) {
try {
let commitsBuffer = execSync(`git log -1 --since='${config.branchAge}' ${branchName}`);
let commitMessages = commitsBuffer ? commitsBuffer.toString().trim() : '';
// if we don't find any commit that is 2 month or less old, then it is old
if(commitMessages.length === 0) {
return true;
}
return false;
} catch(err) {
throw err;
}
}
/**
* @return {Array} - Array of branches that are NOT merged to develop
*/
function findNotMergedBranches() {
try {
execSync(`git branch -r --no-merged develop | grep ${config.filterText} > ${config.notMergedBranches}`, {stdio: ['ignore', 'ignore', 'ignore']});
return fileToArray(config.notMergedBranches);
} catch(err) {
throw err;
}
}
/**
* @return {Array} Array of branches that are merged to develop
*/
function findMergedBranches() {
try {
execSync(`git branch -r --merged develop | grep ${config.filterText} > ${config.mergedBranches}`, {stdio: ['ignore', 'ignore', 'ignore']});
return fileToArray(config.mergedBranches);
} catch(err) {
throw err;
}
}
/**
* @return {Array} - Array of branches that are config.branchAge or older AND not merged
*/
function findNotMergedOldBranches() {
let branchesToBeDeleted = [];
let notMergedBranches = [];
try {
//after getting branches that are not merged, we will filter them down to 2 months or older branches
notMergedBranches = findNotMergedBranches();
branchesToBeDeleted = notMergedBranches.filter(branchName => branchIsOld(branchName))
//save the list to file for safe keeping
fs.writeFileSync(config.notMergedOldBranches, branchesToBeDeleted.join('\n'));
return branchesToBeDeleted;
} catch(err) {
throw err;
}
}
/**
* @param {branches} - An array branch names
*/
function deleteBranches(branches) {
//extra caution against deleting develop or master branches
let parentBranches = ['develop', 'master'];
let filteredBranches = branches.filter(branch => parentBranches.includes(branch) !== true );
filteredBranches.forEach((branch) => {
try {
console.log(branch);
// execSync(`git push origin --delete ${branch}`, {stdio: ['ignore', 'ignore', 'ignore']});
} catch(err) {
throw err;
}
});
}
function init() {
try {
execSync('git checkout develop', {stdio: ['ignore', 'ignore', 'ignore']});
let mergedBranches = findMergedBranches();
let notMergedOldBranches = findNotMergedOldBranches();
deleteBranches(mergedBranches);
deleteBranches(notMergedOldBranches);
} catch(err) {
console.log(err);
}
}
// run the program
init();
@iamtekeste
Copy link
Author

iamtekeste commented May 5, 2017

Updated to reflect input from James Benner which made the code more readable.

@iamtekeste
Copy link
Author

Add code to make the script checkout develop branch first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment