Skip to content

Instantly share code, notes, and snippets.

@carmanchris31
Last active March 24, 2021 02:20
Embed
What would you like to do?
Git Utility (ZSH) - Clean merged branches
# Git Helper: Clean merged branches
# Checks for merged branches against the currently checkout branch. Lists and confirms for deletion.
# To protect branches from ever being deleted, add them to DO_NOT_DELETE. Protected branches will be skipped.
# usage: git-clean
function git-clean() {
local DO_NOT_DELETE=(
master
develop
)
local mergedBranches=()
echo -e "\n\e[34mChecking current branch...\e[0m"
local currentBranch=$(git branch --show-current)
echo " $currentBranch"
DO_NOT_DELETE+=($currentBranch)
echo -e "\n\e[34mLooking for merged branches...\e[0m"
mergedBranches+=$(git branch --merged | awk "/^[^*]/ {print}")
# Detect branches that have been squashed before merging
# @see https://github.com/not-an-aardvark/git-delete-squashed
# Disabled because this is slow and should be covered by checking for branches deleted upstream
# mergedBranches+=$(git for-each-ref refs/heads/ "--format=%(refname:short)" |
# while read branch;
# do mergeBase=$(git merge-base $currentBranch $branch) &&
# [[ $(git cherry $currentBranch $(git commit-tree $(git rev-parse $branch^{tree}) -p $mergeBase -m _)) == "-"* ]] &&
# echo $branch;
# done)
echo -e "\n\e[34mLooking for branches deleted upstream...\e[0m"
mergedBranches+=$(git branch -vv | awk '/: gone\]/ {print $1}')
# Remove duplicates
mergedBranches=$(echo $mergedBranches | sort -u)
local queuedBranches=()
local protectedBranches=()
for branch in $(echo $mergedBranches)
do
# Trim leading whitespace
branch=$(echo $branch | sed 's/^ *//')
if [ $branch = "*" ]; then
# Skip
elif [ ${DO_NOT_DELETE[(Ie)$branch]} -gt "0" ]; then
echo " \e[32mSkipping\e[0m $branch"
protectedBranches+=($branch)
else
queuedBranches+=($branch)
fi
done
if [ -z "$queuedBranches" ]; then
echo -e "\n\e[32mNothing to do here!\e[0m"
else
branchesCount="${#queuedBranches}"
pluralBranches=$([ $branchesCount != "1" ] && echo "$branchesCount branches" || echo "branch")
echo -e "\n\e[93mRemove the following $pluralBranches?\e[0m (Y/N)"
for branch in $queuedBranches
do
echo " $branch"
done
echo "\n"
read -q $'confirm?> '
if [ "$confirm" = "y" ]; then
echo -e "\n\e[34mCleaning branches...\e[0m\n"
echo $queuedBranches | xargs -n 1 git branch -D # FORCE delete (squashed branches)
echo -e "\n\e[32mAll Done!\e[0m\n"
else
echo -e "\n\n\e[33mCanceled\e[0m\n"
return
fi
fi
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment