Created
February 7, 2012 22:53
-
-
Save dominics/1762685 to your computer and use it in GitHub Desktop.
A quick bash script to remove stale remote branches (merged into master, head commit is old) by pushing an empty reference to them
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# vim: set ts=4 sw=4 expandtab tw=79 : | |
# | |
# Asks to delete remote branches that have been merged into master and haven't | |
# been committed to in a fortnight. Also asks to delete unmerged branches that | |
# haven't been committed to in three months. | |
set -e | |
c_red=`tput setaf 1 || tput setf 4` | |
c_yellow=`tput setaf 3 || tput setf 6` | |
c_reset=`tput sgr0` | |
two_weeks_ago=$(date -v-2w +%s) | |
three_months_ago=$(date -v-3m +%s) | |
iso_8601="%Y-%m-%d %H:%M:%S %z" | |
merged_branches=$( \ | |
git branch -ar --merged master --no-color --no-abbrev | \ | |
grep -v -- '->' | \ | |
grep -v 'master' | \ | |
grep -v 'prod' | \ | |
grep -v 'staging' | \ | |
grep -Pv '\sfeature\s' | \ | |
grep '/' | |
) | |
unmerged_branches=$( \ | |
git branch -ar --no-merged master --no-color --no-abbrev | \ | |
grep -v -- '->' | \ | |
grep -v 'master' | \ | |
grep -v 'prod' | \ | |
grep -v 'staging' | \ | |
grep -Pv '\sfeature\s' | \ | |
grep '/' | |
) | |
IFS=" | |
" | |
for branch in $merged_branches; do | |
echo "Branch: $c_yellow$branch$c_reset" | |
remote=$(sed 's/ \([A-Za-z0-9_-]*\)\/.*/\1/' <<< "$branch" | tr -d ' ') | |
name=$(sed 's/.*\/\([A-Za-z0-9_-]*\)/\1/' <<< "$branch") | |
last=$(git show -s --format="%ci" $remote/$name | tr -d '\n') | |
last_timestamp=$(date -jf "$iso_8601" "$last" +%s) | |
echo " Last commit: $last" | |
if [[ $last_timestamp -gt $two_weeks_ago ]]; then | |
echo " Has commit in last fortnight. Skipping." | |
continue | |
else | |
remove="" | |
while [[ $remove != "y" && $remove != "n" ]]; do | |
read -p " No commit in last fortnight. Remove branch? (y/n) " remove | |
done | |
if [[ $remove == "n" ]]; then | |
continue | |
fi | |
fi | |
echo " Removing branch: git push $remote :$name" | |
git push $remote ":$name" | |
done | |
for branch in $unmerged_branches; do | |
echo "Unmerged branch: $c_red$branch$c_reset" | |
remote=$(sed 's/ \([A-Za-z0-9_-]*\)\/.*/\1/' <<< "$branch" | tr -d ' ') | |
name=$(sed 's/.*\/\([A-Za-z0-9_-]*\)/\1/' <<< "$branch") | |
last=$(git show -s --format="%ci" $remote/$name | tr -d '\n') | |
last_timestamp=$(date -jf "$iso_8601" "$last" +%s) | |
number_commits=$(git rev-list $remote/$name ^master | wc -l | tr -d ' ') | |
echo " Last commit: $last" | |
echo " Number of commits: $number_commits" | |
if [[ $last_timestamp -gt $three_months_ago ]]; then | |
echo " Has commit in last three months. Skipping." | |
continue | |
else | |
remove="" | |
while [[ $remove != "y" && $remove != "n" ]]; do | |
read -p " No commit in last three months. Remove branch? (y/n) " remove | |
done | |
if [[ $remove == "n" ]]; then | |
continue | |
fi | |
fi | |
echo " Removing branch: git push $remote :$name" | |
git push $remote ":$name" | |
done | |
echo "All done. Remember to git remote prune $remote" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use this script? Tried but didn't work.
→ ./clean.sh usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]] [-e pattern] [-f file] [--binary-files=value] [--color=when] [--context[=num]] [--directories=action] [--label] [--line-buffered] [--null] [pattern] [file ...]