Last active
April 2, 2024 13:06
-
-
Save matthewpwatkins/ac6e2a4f1c50208398afe7484b24c247 to your computer and use it in GitHub Desktop.
Prune remote branches
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Usage: | |
# bash prune-remote-branches.sh --all-before 2023-08-01 --none-after 2021-03-01 --force | |
# Default values for flags | |
CENTRAL_BRANCH="master" | |
DRY_RUN=true | |
# Parse command line arguments | |
while [[ $# -gt 0 ]]; do | |
case "$1" in | |
-c|--central-branch) | |
CENTRAL_BRANCH="$2" | |
shift | |
;; | |
-b|--all-before) | |
ALL_BEFORE_DATE="$2" | |
shift | |
;; | |
-a|--none-after) | |
NONE_AFTER_DATE="$2" | |
shift | |
;; | |
-f|--force) | |
DRY_RUN=false | |
;; | |
*) | |
echo "Invalid option: $1" | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
if [[ -z "$ALL_BEFORE_DATE" && -z "$NONE_AFTER_DATE" ]]; then | |
echo "Must set either --all-before or --non-after" | |
exit 1 | |
fi | |
get_all_remote_branches() { | |
branch_names=$(git br -r | grep -v " -> " | sed 's/^[[:space:]]*origin\///' | sort) | |
for branch_name in "${branch_names[@]}"; do | |
if [[ "$branch_name" != "CENTRAL_BRANCH" ]]; then | |
echo "$branch_name" | |
fi | |
done | |
} | |
for BRANCH_NAME in $(get_all_remote_branches); do | |
if [[ "$BRANCH_NAME" == "$CENTRAL_BRANCH" ]]; then | |
continue | |
fi | |
LAST_COMMIT=$(git rev-list -n 1 "origin/$BRANCH_NAME") | |
LAST_COMMIT_DATE=$(git show -s --format=%cd --date=format:'%Y-%m-%d' "$LAST_COMMIT") | |
if [[ -n "$NONE_AFTER_DATE" && "$LAST_COMMIT_DATE" > "$NONE_AFTER_DATE" ]]; then | |
continue | |
fi | |
should_delete_branch=false | |
MERGE_BASE=$(git merge-base "origin/$BRANCH_NAME" "origin/$CENTRAL_BRANCH") | |
if [[ "$LAST_COMMIT" == "$MERGE_BASE" ]]; then | |
echo "[$BRANCH_NAME]: Merged to $CENTRAL_BRANCH. Last commit: $LAST_COMMIT - $LAST_COMMIT_DATE" | |
should_delete_branch=true | |
elif [[ -n "$ALL_BEFORE_DATE" && "$LAST_COMMIT_DATE" < "$ALL_BEFORE_DATE" ]]; then | |
echo "[$BRANCH_NAME]: Stale. Last commit: $LAST_COMMIT - $LAST_COMMIT_DATE" | |
should_delete_branch=true | |
fi | |
if [ "$DRY_RUN" = false ] && [ "$should_delete_branch" = true ]; then | |
git push origin --delete "$BRANCH_NAME" | |
fi | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment