Skip to content

Instantly share code, notes, and snippets.

@unarist
Created September 30, 2018 18:35
Show Gist options
  • Save unarist/2f6da154ddb30eb52993713e9d064a83 to your computer and use it in GitHub Desktop.
Save unarist/2f6da154ddb30eb52993713e9d064a83 to your computer and use it in GitHub Desktop.
#!/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