#!/usr/bin/env bash # This script cleans up local Git branches which have been merged into # the main branch. I use it to clean up the branch view in GitUp # (my Git GUI of choice), so I'm not distracted by lots of old branches. # # It's based on the commands from this Stack Overflow post: # https://stackoverflow.com/a/6127884/1558022 set -o errexit set -o nounset GIT_ROOT=$(git rev-parse --absolute-git-dir) if [[ -f "$GIT_ROOT/refs/remotes/origin/HEAD" ]] then PRIMARY_BRANCH=$(cat "$GIT_ROOT/refs/remotes/origin/HEAD" \ | tr '/' ' ' \ | awk '{print $5}') elif [[ -f "$GIT_ROOT/refs/remotes/origin/live" ]] then PRIMARY_BRANCH="live" else PRIMARY_BRANCH="main" fi CURRENT_BRANCH=$(git branch --show-current) if [[ "$PRIMARY_BRANCH" = "$CURRENT_BRANCH" ]] then print_info "-> Current branch is $CURRENT_BRANCH, which is primary" else print_info "-> Primary branch is $PRIMARY_BRANCH" print_info "-> Current branch is $CURRENT_BRANCH" fi for branch in $(git branch --merged "$PRIMARY_BRANCH" | grep -v '*') do if [[ "$branch" == "$PRIMARY_BRANCH" ]] then continue fi if [[ "$branch" == "$CURRENT_BRANCH" ]] then continue fi git branch --delete "$branch" done # For Tailscale repos, the above check doesn't work. Branches get rebased # or squashed before being merged into main, so the branch never shows up # as merged -- it's a different commit in main and the branch. # # Instead, look for alexc/ branches that are more than a fortnight old and # don't exist in the origin. These are branches I've either abandoned or # merged into main. PREFIXES=("alexc/" "danni/" "icio/" "kradalby/" "mpminardi/" "mprovost/" "zofrex/") DAYS_AGO=14 THRESHOLD_DATE=$(date -v-"${DAYS_AGO}"d +%s) for PREFIX in "${PREFIXES[@]}"; do git for-each-ref --format='%(refname:short)' refs/heads/"$PREFIX"* | while read -r branch; do # If the branch still exists on GitHub, ignore it -- this is likely # an active branch with an open PR. if git rev-parse --verify --quiet "origin/$branch" &>/dev/null; then continue fi # When did I last commit to this branch? commit_timestamp=$(git log -1 --format="%at" "$branch") if (( commit_timestamp > THRESHOLD_DATE )); then continue fi git branch --delete --force "$branch" done done