Skip to content

Instantly share code, notes, and snippets.

@fredrikhl
Last active August 29, 2015 14:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fredrikhl/613a6151f690baf53e98 to your computer and use it in GitHub Desktop.
Save fredrikhl/613a6151f690baf53e98 to your computer and use it in GitHub Desktop.
Delete branches with no upstream
#!/bin/bash
#
# Usage: Run `git-branch-cleanup.sh' in a git repository
# OR `git branch-cleanup' if the script is in your ${PATH}
#
# git_branch_delete
#
# Delete a given branch if not the current branch
# Actually, we could just run git branch -d 'branch', and let that handle
# errors. Meh, I already did this anyway.
#
function git_branch_delete # branchname
{
local branch="$1" current=$( git rev-parse --abbrev-ref HEAD ) commit="$2"
# Assert that a branch name is given
[ -z "${branch}" ] && echo "Usage: git_branch_delete <branchname>" && return 1
# Assert that we can read out the current branch
[ -z "${current}" ] && echo "Error: No selected branch" && return 2
# Check if we're trying to delete the current branch
if [ "${branch}" = "${current}" ]; then
echo "Error: Currently on branch '${current}', can't delete"
return 3
fi
# Actually delete
if [ -n "${commit}" ]; then
echo "Deleting branch '${branch}'"
git branch -d "${branch}"
return $?
fi
echo "git branch -d '${branch}'"
return 0
}
# An array of local branches with missing upstream branch
noremote=()
#
# Gather branches without upstream
#
while read local remote
do
[ -z "$local" ] && continue # This is probably an error
# No remote? If so, keep track of the local branch name
[ -z "$remote" ] && noremote+=( "${local}" ) && continue
# Unable to connect local+remote? If so, keep track of local branch name
git rev-list --left-right ${local}...${remote} --quiet || noremote+=( "${local}" )
done < <( git for-each-ref --format="%(refname:short) %(upstream:short)" refs/heads )
echo "noremote: ${noremote[@]}"
# Quit if we have no local branches with missing upstream branch
[ ${#noremote[@]} -eq 0 ] && echo "No branches with missing upstream" && exit 0
# List branches
echo "Branches without upstream:"
for missing in ${noremote[@]}; do
echo " ${missing}"
done
echo ""
# We don't commit yet, so
echo "To delete, run..."
# List commands to delete local branch.
for missing in ${noremote[@]}; do
git_branch_delete "${missing}" # Add "commit" arg here to actually delete
done
# Quit if the current branch is in the array of found brances
#for missing in ${noremote[@]}; do
#[ "${missing}" != "${current}" ] && continue
#echo "Currently on branch '${current}', can't delete."
#exit 1
#done
# TODO: We should list the branches, and ask interactively if we want to delete
# them.
# If [y], delete branches
# If [n], list delete command for each branch
#
# If implemented, we should also consider arguments (e.g. non-interactive
# flags to delete or list commands).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment