Automate Git Branch Management with Shell Scripts

📖 3 minutes read

Managing multiple feature branches in a Laravel project can be tedious—especially when you need to rebase them all onto master before a release. Instead of manually running the same Git commands for each branch, automate it with a shell script.

The Manual Process

# For each branch, manually run:
git checkout master
git checkout origin/feature/user-dashboard
git rebase master
git push origin HEAD:feature/user-dashboard --force

git checkout master
git checkout origin/feature/api-endpoints
git rebase master
git push origin HEAD:feature/api-endpoints --force

# ...repeat for every branch

This is error-prone and wastes time. You might forget a branch, push to the wrong remote, or leave the repository in a bad state if you hit conflicts.

The Automated Approach

Create a rebase-branches.sh script that handles the entire workflow with proper error handling:

#!/bin/bash
# rebase-branches.sh

set -e

# Parse arguments
TARGET_BRANCH="master"
while [[ $# -gt 0 ]]; do
    case $1 in
        -t|--target)
            TARGET_BRANCH="$2"
            shift 2
            ;;
        *)
            BRANCHES+=("$1")
            shift
            ;;
    esac
done

# Validate repository
REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
if [[ "$REMOTE_URL" != "[email protected]:yourcompany/yourapp.git" ]]; then
    echo "Error: Must run from correct repository"
    exit 1
fi

echo "Fetching from origin..."
git fetch origin

SKIPPED=()
SUCCESSFUL=()

for branch in "${BRANCHES[@]}"; do
    echo "Processing: $branch"
    
    # Checkout target branch
    if ! git checkout "$TARGET_BRANCH" 2>/dev/null; then
        SKIPPED+=("$branch (checkout failed)")
        continue
    fi
    
    # Checkout feature branch from origin
    if ! git checkout "origin/$branch" 2>/dev/null; then
        SKIPPED+=("$branch (branch not found)")
        continue
    fi
    
    # Attempt rebase
    if git rebase "$TARGET_BRANCH" 2>/dev/null; then
        # Force push if successful
        if git push origin "HEAD:$branch" --force 2>/dev/null; then
            SUCCESSFUL+=("$branch")
        else
            SKIPPED+=("$branch (push failed)")
            git rebase --abort 2>/dev/null || true
        fi
    else
        # Abort on conflicts
        git rebase --abort 2>/dev/null || true
        SKIPPED+=("$branch (conflicts)")
    fi
done

# Return to target branch
git checkout "$TARGET_BRANCH" 2>/dev/null || true

# Report results
echo "Successfully rebased: ${#SUCCESSFUL[@]}"
for branch in "${SUCCESSFUL[@]}"; do
    echo "  ✓ $branch"
done

if [ ${#SKIPPED[@]} -gt 0 ]; then
    echo "Skipped (conflicts/errors): ${#SKIPPED[@]}"
    for branch in "${SKIPPED[@]}"; do
        echo "  ✗ $branch"
    done
fi

Usage

# Make it executable
chmod +x rebase-branches.sh

# Rebase onto master (default)
./rebase-branches.sh feature/user-dashboard feature/api-endpoints feature/admin-tools

# Rebase onto a different branch
./rebase-branches.sh -t develop feature/user-dashboard feature/api-endpoints

What It Does

  • Validates repository: Prevents accidentally running it in the wrong project
  • Fetches from origin: Ensures you’re working with latest remote changes
  • Handles conflicts gracefully: Aborts rebase and continues to next branch instead of leaving you in a broken state
  • Reports results: Shows you exactly which branches succeeded and which had issues
  • Returns to safe state: Always checks out the target branch when done

Why This Matters

Automating repetitive Git workflows saves time and reduces errors. This script is idempotent—if something fails, it cleans up and moves on without leaving your repository in a broken state. Perfect for teams managing multiple long-running feature branches that need frequent rebasing onto master or develop.

The script pattern can be adapted for other batch Git operations: merging multiple branches, deleting stale branches, or updating multiple repositories at once.

Daryle De Silva

VP of Technology

11+ years building and scaling web applications. Writing about what I learn in the trenches.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *