Skip to content

Instantly share code, notes, and snippets.

@sachin-handiekar
Created August 15, 2025 13:21
Show Gist options
  • Save sachin-handiekar/3d1da8377a6c38b71e01f55e69504840 to your computer and use it in GitHub Desktop.
Save sachin-handiekar/3d1da8377a6c38b71e01f55e69504840 to your computer and use it in GitHub Desktop.
Delete Git Remote branches
#!/bin/bash
# Script to delete remote Git branches older than 1 year
# Usage: ./delete_old_branches.sh [remote_name] [--dry-run]
# Default remote is 'origin'
set -e
# Configuration
REMOTE_NAME="${1:-origin}"
DRY_RUN=false
ONE_YEAR_AGO=$(date -d "1 year ago" +%s)
# Check for dry-run flag
if [[ "$*" == *"--dry-run"* ]]; then
DRY_RUN=true
echo "πŸ” DRY RUN MODE - No branches will be deleted"
fi
echo "πŸ” Checking for branches older than 1 year on remote '$REMOTE_NAME'..."
echo "πŸ“… Cutoff date: $(date -d "1 year ago" '+%Y-%m-%d')"
echo ""
# Fetch latest remote information
echo "πŸ“‘ Fetching latest remote information..."
git fetch "$REMOTE_NAME" --prune
# Get list of remote branches (excluding HEAD)
remote_branches=$(git branch -r | grep "$REMOTE_NAME/" | grep -v "HEAD" | sed "s|$REMOTE_NAME/||" | tr -d ' ')
if [ -z "$remote_branches" ]; then
echo "❌ No remote branches found for '$REMOTE_NAME'"
exit 1
fi
branches_to_delete=()
protected_branches=("main" "master" "develop" "development" "staging" "production")
echo "πŸ” Analyzing branches..."
echo ""
for branch in $remote_branches; do
# Skip protected branches
if [[ " ${protected_branches[@]} " =~ " ${branch} " ]]; then
echo "πŸ›‘οΈ Skipping protected branch: $branch"
continue
fi
# Get the last commit date for the branch
last_commit_date=$(git log -1 --format="%ct" "$REMOTE_NAME/$branch" 2>/dev/null || echo "0")
if [ "$last_commit_date" -eq 0 ]; then
echo "⚠️ Could not get commit date for branch: $branch"
continue
fi
# Check if branch is older than 1 year
if [ "$last_commit_date" -lt "$ONE_YEAR_AGO" ]; then
last_commit_human=$(date -d "@$last_commit_date" '+%Y-%m-%d')
echo "πŸ—‘οΈ Branch '$branch' is old (last commit: $last_commit_human)"
branches_to_delete+=("$branch")
else
last_commit_human=$(date -d "@$last_commit_date" '+%Y-%m-%d')
echo "βœ… Branch '$branch' is recent (last commit: $last_commit_human)"
fi
done
echo ""
if [ ${#branches_to_delete[@]} -eq 0 ]; then
echo "✨ No old branches found to delete!"
exit 0
fi
echo "πŸ“‹ Summary:"
echo " Found ${#branches_to_delete[@]} branch(es) older than 1 year"
echo ""
if [ "$DRY_RUN" = true ]; then
echo "πŸ” DRY RUN - Would delete the following branches:"
for branch in "${branches_to_delete[@]}"; do
echo " - $REMOTE_NAME/$branch"
done
echo ""
echo "πŸ’‘ Run without --dry-run to actually delete these branches"
exit 0
fi
# Confirm deletion
echo "⚠️ WARNING: This will permanently delete the following remote branches:"
for branch in "${branches_to_delete[@]}"; do
echo " - $REMOTE_NAME/$branch"
done
echo ""
read -p "Are you sure you want to continue? (y/N): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo "❌ Operation cancelled"
exit 0
fi
echo ""
echo "πŸ—‘οΈ Deleting old branches..."
deleted_count=0
failed_count=0
# Commented out - only printing list of branches instead of deleting
# for branch in "${branches_to_delete[@]}"; do
# echo -n " Deleting $REMOTE_NAME/$branch... "
# if git push "$REMOTE_NAME" --delete "$branch" 2>/dev/null; then
# echo "βœ… Done"
# ((deleted_count++))
# else
# echo "❌ Failed"
# ((failed_count++))
# fi
# done
# Just print the list of branches that would be deleted
for branch in "${branches_to_delete[@]}"; do
echo " πŸ“‹ Would delete: $REMOTE_NAME/$branch"
((deleted_count++))
done
echo ""
echo "πŸ“Š Results:"
echo " βœ… Successfully deleted: $deleted_count branches"
if [ $failed_count -gt 0 ]; then
echo " ❌ Failed to delete: $failed_count branches"
fi
echo ""
echo "πŸŽ‰ Cleanup complete!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment