Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Delete local and remote branches which have been merged with your current base branch, avoiding to delete master and a branch name
#!/bin/bash
#
# With execute permissions of this bash file.
# Checkout on master branch
# Replace <custom_branch> by the branch you want to avoid to be removed (in case any) - for instance: development / staging
# Run:
# - ./git-delete-merged-script.sh -h --- print help
# - ./git-delete-merged-script.sh -r origin --- to delete remote branches based on remote: origin
# - ./git-delete-merged-script.sh -l origin --- to delete local branches based on remote: origin
# - ./git-delete-merged-script.sh -rl origin --- to delete remote and local branches based on remote: origin
# - ./git-delete-merged-script.sh -dr origin --- simulate the remote deletion without actually running it
delete_local=false
delete_remote=false
dry_run=false
origin_name=origin
show_help ()
{
echo "usage: $0 options origin_name"
echo ""
echo "options"
echo " -h show help"
echo " -r delete remote branch"
echo " -l delete local branch"
echo " -d dry-run mode, to see what branches will be removed"
exit 0
}
while getopts "hrld" opt; do
case $opt in
h)
show_help
;;
r)
delete_remote=true
;;
l)
delete_local=true
;;
d)
dry_run=true
;;
:)
exit 1
;;
esac
done
if [ $# -ne 2 ];
then
echo "usage: ./script -options origin_name"
exit 0;
fi
origin_name=$2
echo -e "Will be checking the remote origin: ${origin_name}"
if ! $delete_local && ! $delete_remote;
then
echo -e "Well, no specify -r or -l, quit"
exit 1
fi
if $dry_run ;
then
echo -e "Running in dry-run mode..."
fi
touch_branches_message=""
if $delete_local;
then
touch_branches_message="local, "
fi
if $delete_remote ;
then
touch_branches_message=$touch_branches_message"remote"
fi
echo -e "Delete merged branches: ${touch_branches_message}"
################################################################
#
# Update
#
################################################################
remote_custom_branch_branch="remotes/${origin_name}/<custom_branch>"
remote_master_branch="remotes/${origin_name}/master"
custom_branch_branch="<custom_branch>"
master_branch="master"
declare -a remote_merged_branches
declare -a local_merged_branches
current_branch=`git branch|grep "*"|sed s/^*//`
echo -e "Base on current local branch: $current_branch"
echo -e "Update current branch to date and prune deleted remote branches..."
git fetch -p && git pull origin $current_branch
if [ $? != 0 ];
then
echo -e "... Fail to update!"
exit 1
fi
################################################################
#
# Find merged remote & local branches
#
################################################################
echo -e "Find already merged branches..."
i=0
j=0
for k in $(git branch -a --merged|grep -v "\->"|sed s/^..//);
do
if ! `echo ${k} | grep -E "^${remote_custom_branch_branch}|^${remote_master_branch}|^${master_branch}" 1>/dev/null 2>&1`;
then
remote_merged_branches[i++]=`echo ${k} | sed -e "s/^remotes\/${origin_name}\///"`
fi
if ! `echo ${k} | grep -E "^${custom_branch_branch}|^${master_branch}|^${master_branch}" 1>/dev/null 2>&1`;
then
local_merged_branches[j++]=`echo ${k} | sed -e "s/^remotes\/${origin_name}\///"`
fi
done
################################################################
#
# Delete remote & local branches
#
################################################################
#
# for branch in ${remote_merged_branches[@]};
# do
# echo ${branch}
# done
#
# exit 1
if $delete_remote ;
then
echo -e "Delete remote branches..."
for branch in ${remote_merged_branches[@]};
do
if $dry_run ;
then
echo "Delete: $branch"
else
echo "About to delete: $branch"
git push origin :$branch
fi
done
fi
if $delete_local ;
then
echo -e "Delete local branches..."
for branch in ${local_merged_branches[@]};
do
if $dry_run ;
then
echo "Delete: $branch"
else
git branch -D $branch 2>/dev/null
fi
done
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment