Skip to content

Instantly share code, notes, and snippets.

@iamtekeste
Last active May 8, 2017 13:17
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iamtekeste/4d8a6daaff18f8415dae46926efc1e66 to your computer and use it in GitHub Desktop.
Save iamtekeste/4d8a6daaff18f8415dae46926efc1e66 to your computer and use it in GitHub Desktop.
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