Skip to content

Instantly share code, notes, and snippets.

@drGrove
Last active January 13, 2018 05:55
Show Gist options
  • Save drGrove/afc0c1294a7ac898b25139634ded273e to your computer and use it in GitHub Desktop.
Save drGrove/afc0c1294a7ac898b25139634ded273e to your computer and use it in GitHub Desktop.
Git Repo cleanup (For Linux and MacOS)
#!/bin/bash
output_type='text'
days_back='60'
branch_command=`git branch -r | grep -v HEAD`
dryrun=false
sanityCheck=false
protected=("master" "develop" "origin/master" "origin/develop")
get_backlog_date() {
local backlog_date=""
if [[ "$(uname)" == "Darwin" ]]; then
backlog_date=$(date -v-${days_back}d +%s)
else
backlog_date=$(date -d"now-${days_back}days" +%s)
fi
return $backlog_date
}
containsElement () {
local e
for e in "${@:2}";
do
[[ "$e" == "$1" ]] && return 0;
done
return 1
}
usage() {
echo "$(basename "$0") [-h] [-o TEXT] [-m -nm -dryrun] [-d NUMBER]
where:
-h|--help show this help text
-o TEXT set the output (text or csv). Text is default, CSV will force dryrun.
-m Only search for branches that have been merged and meet the days_back
-nm Only search for branches that have not been merged and meet the days_back
-d NUMBER Number of days to go back. Defaults to 60
--dryrun Will only output the list of branches to be deleted
"
}
_setArgs() {
while [ "$1" != "" ]; do
case $1 in
"-h" | "--help")
usage
exit
;;
"-o" | "--output")
shift
if [ $1 != "csv" ] && [ $1 != "text" ]; then
echo "Only allowed types are csv and text."
exit 1
fi
output_type=$1
dryrun=true
;;
"-m" | "--merged")
branch_command=`git branch -r --merged | grep -v HEAD`
;;
"-nm" | "--not-merged")
branch_command=`git branch -r --no-merged | grep -v HEAD`
;;
"-d" | "--days")
shift
days_back=$1
;;
"--dryrun")
dryrun=true
;;
esac
shift
done
}
get_converted_date() {
local converted_date=""
if [[ "$(uname)" == "Darwin" ]]; then
converted_date=$(date -j -f "%Y-%m-%d %T %z" "${last_touched}" +%s)
else
converted_date=$(date -d"${last_touched}" +%s)
fi
return $converted_date
}
main() { if [[ $output_type == "csv" ]]; then
echo "Branch, Last Commited To"
fi
for branch in $branch_command;
do
last_touched=`git show --format="%ci" $branch | head -n 1`
months_ago=`git show --format="%cr" $branch | head -n 1`
coverted_date=$(get_converted_date)
# Stringify months ago for csv output
if [[ $output_type == "csv" ]]; then
months_ago="\"${months_ago}\""
fi
# Rewrite branch name to drop origin
branch="${branch/origin\/}"
# Check if the last commit is greater than the backlog date
if [ $backlog_date -ge $converted_date ]; then
if (containsElement "${branch}" "${protected[@]}") ; then
echo "Skipping protected branch: ${branch}"
continue
fi
if [[ $output_type == "csv" ]]; then
echo "${branch},${months_ago}"
else
echo "${branch}"
fi
fi
if [ ! $dryrun ]; then
branches_to_delete+=($branch)
fi
done
if [ ! $dryrun ] && [ sanityCheck ]; then
delete_branches $branches_to_delete
fi
}
delete_branches() {
local branches="$1"
for branch in "${branches[@]}";
do
deleteBranch $branch
done
}
sanityCheck() {
echo "Are you sure you want to delete all branches that have not had a commit
in the last ${days_back} days? (This will also prune local branches) (y/N)"
read check_value
return [[ "${check_value}" == "y" ]]
}
deleteBranch() {
local branch=$1
echo "Deleting ${branch}"
git push origin :$branch
git fetch -p
}
# Run the main function
_setArgs "$@"
backlog_date=$(get_backlog_date)
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment