Skip to content

Instantly share code, notes, and snippets.

@jonathan-beebe
Last active April 13, 2021 13:42
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jonathan-beebe/a953fe21c4cb8c00cf71f10975abc094 to your computer and use it in GitHub Desktop.
Save jonathan-beebe/a953fe21c4cb8c00cf71f10975abc094 to your computer and use it in GitHub Desktop.
git: Find all merged ancestors branches and create commands to delete them.

To find all ancestor branches

./get_ancestor_branches.sh

To create the delete commands for all ancestor branches and echo them as text (not invoking them)

./get_ancestor_branches.sh | ./delete_branches.sh

To invoke the delete commands to actually perform the work

./get_ancestor_branches.sh | ./delete_branches.sh | bash -
#!/bin/bash
# Input: takes a list of git branches as input.
# Output: outputs a list of git commands to delete the input branches.
#
# Great post on deleting branches in git:
# http://stackoverflow.com/a/23961231/123781
# Set `input` to grab the first argument, or the stdin.
[ $# -ge 1 -a -f "$1" ] && input="$1" || input=$(cat)
# Loop over each branch, creating command to delete from local and remote git repo
for branch in ${input[@]}; do
case "$branch" in
origin/* )
# handle remotes/origin case
branchName="$(echo $branch | sed 's/origin\///')"
command="git push origin --delete $branchName"
;;
*)
# handle the local branch case
command="git branch -d $branch"
;;
esac
echo $command
done
#!/bin/bash
# Find all local and remote ancestor branches that have been merged into the root branch
# ---------
# Config
# Set the root branch name.
# e.g. if you want to find all ancestors of master,
# then set this to use `origin/master`
ROOT_BRANCH=origin/master
# Get the hash of the parent repo
ROOT_HASH="$(git rev-parse $ROOT_BRANCH 2>&-)"
# A list of protected repos that should never be operated on automatically
# meaning this script will _not_ create delete commands for these branches.
PROTECTED_BRANCHES=(master origin/master PROD origin/PROD BETA origin/BETA DEV origin/DEV)
# END Config
# ---------
# 1. Find all merged branches
FIND_BRANCH_COMMAND="git for-each-ref --sort=-committerdate --format='%(objectname):%(refname:short)' refs/heads/ refs/remotes/ --merged"
for branchName in ${PROTECTED_BRANCHES[@]}; do
FIND_BRANCH_COMMAND+=" | grep -v $branchName"
done
FOUND_BRANCHES=`eval $FIND_BRANCH_COMMAND`
# 2. Filter branches down to only those ancestors fully merged into root branch.
ANCESTORS=()
for branch in $FOUND_BRANCHES; do
HASH="$(echo $branch | awk -F":" '{print $1}')"
REF="$(echo $branch | awk -F":" '{print $2}')"
if $(git merge-base --is-ancestor "$HASH" "$ROOT_HASH"); then
ANCESTORS+=($REF)
fi
done
echo ${ANCESTORS[@]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment