Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/bin/bash
set -eu
master=upstream/master
ourremote=origin
ignore_pattern="^pr/|^(master|develop)$"
skip_pattern="^(test|draft)/"
candidates=()
skipped=()
echo "Checking branches..."
while read branch stat remote; do
if [[ $branch =~ $ignore_pattern ]]; then
continue
elif [[ $remote != $ourremote || $branch =~ $skip_pattern ]]; then
skipped+=($branch)
continue
elif [[ $stat = "[]" && $remote != "" ]]; then
# disabled because now we encourages "git push -d" for candidates.
# use "purged-branches" alias instead.
continue
#candidates+=($branch)
#echo $branch: upstream deleted
elif git merge-base --is-ancestor $branch $master; then
candidates+=($branch)
echo $branch: merged
else
# check squash merge state
mergeBase=$(git merge-base $master $branch)
squashed=$branch
if [[ $(git rev-parse $branch^) != $mergeBase ]]; then
squash=$(git commit-tree $(git rev-parse $branch^{tree}) -p $mergeBase -m _)
fi
if [[ $(git cherry $master $squashed) == "-"* ]]; then
candidates+=($branch)
echo $branch: squash merged
else
echo "# $branch: looks active"
fi
fi
done < <(git for-each-ref --format '%(refname:short) [%(upstream:trackshort)] %(upstream:remotename)' refs/heads)
echo "Done."
if (( ${#skipped[@]} )); then
echo ""
echo "Note that below branches were skipped:"
printf " %s\n" ${skipped[@]}
fi
echo ""
if (( ${#candidates[@]} )); then
echo "To remove all candidate branches from remote, run this:"
echo ""
echo "git push $ourremote -d ${candidates[@]}"
else
echo "No obsolete branches were detected."
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.