Skip to content

Instantly share code, notes, and snippets.

@azatoth
Forked from GrayedFox/git-glean
Last active December 2, 2022 13:27
Show Gist options
  • Save azatoth/3a34cdebb59e252b80e920ce531c5289 to your computer and use it in GitHub Desktop.
Save azatoth/3a34cdebb59e252b80e920ce531c5289 to your computer and use it in GitHub Desktop.
Remove local branches with a missing (gone) upstream
#!/usr/bin/env bash
# reset environment variables that could interfere with normal usage
unset GREP_OPTIONS
#
# check whether current directory is inside a git repository
#
is_git_repo() {
git rev-parse --show-toplevel >/dev/null 2>&1
result=$?
if test $result != 0; then
echo >&2 'Not a git repo!'
exit $result
fi
}
usage() {
cat <<EOS
Usage:
git delete-gone-branches [-f] [-d]
-f - Force deletion of locally unmerged branches
-d - Dry run; Only list what will be deleted
EOS
}
is_git_repo
# Use colors, but only if connected to a terminal, and that terminal
# supports them.
if which tput >/dev/null 2>&1; then
ncolors=$(tput colors)
fi
if [[ -t 1 ]] && [[ -n "$ncolors" ]] && [[ "$ncolors" -ge 8 ]] ; then
RED="$(tput setaf 1)"
GREEN="$(tput setaf 2)"
YELLOW="$(tput setaf 3)"
BOLD="$(tput bold)"
NORMAL="$(tput sgr0)"
BOLD=$(tput bold)
UNDERLINE=$(tput smul)
NORMAL=$(tput sgr0)
COLOR=always
else
RED=""
GREEN=""
YELLOW=""
BOLD=""
NORMAL=""
BOLD=""
UNDERLINE=""
NORMAL=""
COLOR=never
fi
# first we prune origin to ensure our local list of remote branches is up to date
git remote prune origin
while getopts "fd" opt; do
case $opt in
f)
FORCE=true
;;
d)
DRY_RUN=true
;;
*)
usage
exit 1
;;
esac
done
shift $((OPTIND - 1))
GONE_BRANCHES=$(git branch -vv | grep -v "\+\|\*" | grep 'origin/.*: gone]' | awk '{print $1}')
if [ -z "$GONE_BRANCHES" ]; then
echo "Could not find any local branches that have a gone remote"
exit 0
fi
if [ "$DRY_RUN" ]; then
echo -e "Would remove following branches:\n"
while read -r branch; do
echo "${YELLOW} $branch${NORMAL}"
done <<<"$GONE_BRANCHES"
elif [ "$FORCE" = true ]; then
echo "$GONE_BRANCHES" | xargs git branch -D
else
if ! echo "$GONE_BRANCHES" | xargs git branch -d; then
cat<<-EOF
${RED}
Error: Some local branches are not fully merged.
If you are sure you want to delete them, run
${NORMAL}git delete-gone-branches -f${RED}
to force their deletion.
${NORMAL}
EOF
exit $?
fi
fi
# Handy script when following GitFlow and rebasing, since `git branch --merged master` will never list
# a rebased but merged branch (as their commit history differs).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment