Skip to content

Instantly share code, notes, and snippets.

@bmwant
Last active March 26, 2019 16:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmwant/214048e9abad0e330331baa262e0201a to your computer and use it in GitHub Desktop.
Save bmwant/214048e9abad0e330331baa262e0201a to your computer and use it in GitHub Desktop.
Delete git outdated branches
#!/usr/bin/env bash
set -e
# Reset in case getopts has been used previously in the shell.
OPTIND=1
DRY_RUN=0
KEEP_MONTHS=6 # remove only branches older than keep value
GIT_REF_PREFIX="refs/remotes/origin"
EXCLUDE=('INT' 'QA' 'STAGE' 'master')
EXCLUDE_REGEX="^($(IFS=\|; echo "${EXCLUDE[*]}"))$"
CYAN='\033[0;36m'
RED='\033[0;31m'
NC='\033[0m'
function warn() {
echo -e "${RED}$@${NC}"
}
function info() {
echo -e "${CYAN}$@${NC}"
}
function usage {
cat <<USAGE
Usage: $0 [OPTION] ...
Arguments:
-d, dry-run, just print
-m, delete branches older than X, default is ${KEEP_MONTHS}
USAGE
}
function cleanup_old_branches {
info "Fetching remote branches..."
git fetch
# list just remote branches
# git branch --remotes | wc -l
tmpfilename=$(mktemp /tmp/old.branches.XXXX)
branches=$(git for-each-ref --sort=-committerdate ${GIT_REF_PREFIX} --format='%(refname) | %(committerdate:short) | %(authorname) | %(authoremail)' > ${tmpfilename})
if [ $DRY_RUN -eq 1 ]; then
warn "DRY RUN. Just listing outdated branches without any actions!"
fi
info "Branches outdated for ${KEEP_MONTHS} months:\n"
while IFS='' read -r line || [[ -n "$line" ]]; do
fullbranch=$(echo "${line}" | awk -F "|" '{print $1}')
branch=${fullbranch#"${GIT_REF_PREFIX}/"} # remove prefix
branch="${branch%% }" # trim trailing whitespace
if [[ $branch =~ $EXCLUDE_REGEX ]]; then
warn "Skipping excluded branch [${branch}]..."
continue
fi
commit_date=$(echo "${line}" | awk -F "|" '{print $2}')
if [[ "${OSTYPE}" == "linux-gnu" ]]; then
commit_timestamp=$(date -d "${commit_date}" +%s)
outdated_timestamp=$(date -d "$(date +%Y-%m-%d) -${KEEP_MONTHS} month" +%s)
elif [[ "${OSTYPE}" == "darwin"* ]]; then
commit_timestamp=$(date -jf %Y-%m-%d ${commit_date} +%s)
outdated_timestamp=$(date -jf %Y-%m-%d -v-${KEEP_MONTHS}m $(date +%Y-%m-%d) +%s)
else
warn "Unsupported platform. Script will not work properly!"
exit 1
fi
# if last commit in branch was earlier than KEEP_MONTHS from now
if [ $commit_timestamp -le $outdated_timestamp ]; then
if [ $DRY_RUN -eq 1 ]; then
info "${line}"
else
warn "REMOVING [${branch}] from remote..."
info "${line}\n"
git push origin --delete "${branch}"
fi
fi
done < "${tmpfilename}"
rm "${tmpfilename}"
}
while getopts "hdm:" opt; do
case "$opt" in
h)
usage
exit 0
;;
d)
DRY_RUN=1
;;
m)
KEEP_MONTHS=$OPTARG
;;
esac
done
shift $((OPTIND-1))
cleanup_old_branches
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment