Created
September 25, 2025 13:38
-
-
Save wch/cc51dd0edf6b245c1680a3c211a14a6b to your computer and use it in GitHub Desktop.
Rebase git branch, reformatting each changed file with prettier after each commit
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 | |
| # Rebase with Prettier - Automatically reformat files with prettier during rebase | |
| # | |
| # USAGE: | |
| # ./rebase-prettier-exec.sh | |
| # | |
| # BEFORE RUNNING: | |
| # - Make sure you're on the branch you want to rebase (e.g., your feature branch) | |
| # - This script will rebase your current branch onto origin/main | |
| # - Ensure origin/main is up to date: git fetch origin | |
| # | |
| # DESCRIPTION: | |
| # This script helps rebase your current branch onto origin/main while automatically | |
| # converting space indentation to tab indentation using Prettier. It's designed | |
| # to handle the common problem where your branch uses spaces but the main branch | |
| # has switched to tabs. | |
| # | |
| # HOW IT WORKS: | |
| # 1. Creates a backup branch for safety | |
| # 2. Starts rebase with --ignore-space-change strategies to minimize conflicts | |
| # 3. Runs Prettier after each commit using git's --exec flag | |
| # 4. Only formats files that were changed in each original commit | |
| # 5. Preserves commit messages and history | |
| # | |
| # REQUIREMENTS: | |
| # - npm/npx and Prettier must be installed (run 'npm install' first) | |
| # - Your project should have a .prettierrc config that specifies tabs | |
| # | |
| # CONFLICT RESOLUTION: | |
| # If conflicts occur: | |
| # 1. Fix the merge conflicts in your editor | |
| # 2. Run: npx prettier --write <file> on each resolved file | |
| # 3. Stage: git add <file> | |
| # 4. Continue: git rebase --continue | |
| # | |
| # TO ABORT: | |
| # git rebase --abort | |
| # git checkout <backup-branch-name> | |
| set -e | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| NC='\033[0m' # No Color | |
| echo -e "${BLUE}=== Rebase with Prettier (using --exec) ===${NC}" | |
| echo "" | |
| # Check if prettier is available | |
| if ! command -v npx &> /dev/null || ! npx prettier --version &> /dev/null; then | |
| echo -e "${RED}Error: Prettier is not available${NC}" | |
| echo "Make sure you have run 'npm install' in this project" | |
| exit 1 | |
| fi | |
| # Check if we're in the middle of a rebase | |
| if [ -d ".git/rebase-merge" ] || [ -d ".git/rebase-apply" ]; then | |
| echo -e "${RED}Error: A rebase is already in progress!${NC}" | |
| echo "Finish or abort the current rebase first with:" | |
| echo " git rebase --continue OR git rebase --abort" | |
| exit 1 | |
| fi | |
| # Get current branch name | |
| CURRENT_BRANCH=$(git branch --show-current) | |
| if [ -z "$CURRENT_BRANCH" ]; then | |
| echo -e "${RED}Error: Not on a branch${NC}" | |
| exit 1 | |
| fi | |
| # Create backup | |
| BACKUP_BRANCH="${CURRENT_BRANCH}-backup-$(date +%Y%m%d-%H%M%S)" | |
| echo -e "${YELLOW}Creating backup branch: ${BACKUP_BRANCH}${NC}" | |
| git branch "$BACKUP_BRANCH" | |
| # Create a prettier formatting script | |
| PRETTIER_SCRIPT=$(mktemp /tmp/prettier-format-XXXXXX.sh) | |
| cat > "$PRETTIER_SCRIPT" << 'EOF' | |
| #!/bin/bash | |
| # Format changed files with prettier | |
| # Get list of files changed in the last commit | |
| FILES=$(git diff --name-only HEAD~1..HEAD 2>/dev/null | grep -E '\.(ts|tsx|js|jsx)$' || true) | |
| if [ -n "$FILES" ]; then | |
| echo "Formatting files with Prettier..." | |
| echo "$FILES" | while read -r file; do | |
| if [ -f "$file" ]; then | |
| echo " → $file" | |
| npx prettier --write "$file" 2>/dev/null || true | |
| # Only add this specific file that was part of the original commit | |
| git add "$file" 2>/dev/null || true | |
| fi | |
| done | |
| # Amend the commit if there are changes | |
| if ! git diff --cached --quiet; then | |
| git commit --amend --no-edit --no-verify | |
| echo "✓ Formatting applied to commit" | |
| fi | |
| fi | |
| EOF | |
| chmod +x "$PRETTIER_SCRIPT" | |
| echo -e "${GREEN}Starting rebase onto origin/main...${NC}" | |
| echo "Configuration:" | |
| echo " - Using ignore-space strategies to minimize conflicts" | |
| echo " - Running Prettier after each commit" | |
| echo " - Backup saved to: $BACKUP_BRANCH" | |
| echo "" | |
| # Perform the rebase with --exec to run prettier after each commit | |
| if git rebase origin/main \ | |
| --strategy=recursive \ | |
| --strategy-option=ignore-space-change \ | |
| --strategy-option=ignore-all-space \ | |
| --exec "$PRETTIER_SCRIPT"; then | |
| echo "" | |
| echo -e "${GREEN}=== Rebase completed successfully! ===${NC}" | |
| echo "" | |
| # Run prettier on all files one final time | |
| echo "Running final Prettier pass..." | |
| git diff origin/main --name-only | grep -E '\.(ts|tsx|js|jsx|css)$' | while read -r file; do | |
| if [ -f "$file" ]; then | |
| npx prettier --write "$file" 2>/dev/null || true | |
| git add "$file" 2>/dev/null || true | |
| fi | |
| done | |
| # Amend if needed | |
| if ! git diff --cached --quiet; then | |
| git commit --amend --no-edit --no-verify | |
| echo -e "${GREEN}✓ Final formatting applied${NC}" | |
| fi | |
| echo "" | |
| echo -e "${GREEN}✓ All commits have been rebased and formatted${NC}" | |
| echo "" | |
| echo "To delete the backup:" | |
| echo -e " ${BLUE}git branch -D $BACKUP_BRANCH${NC}" | |
| else | |
| echo "" | |
| echo -e "${YELLOW}=== Rebase needs manual intervention ===${NC}" | |
| echo "" | |
| # Check for conflicts | |
| CONFLICTED_FILES=$(git diff --name-only --diff-filter=U 2>/dev/null || true) | |
| if [ -n "$CONFLICTED_FILES" ]; then | |
| echo -e "${YELLOW}Files with conflicts:${NC}" | |
| echo "$CONFLICTED_FILES" | while read -r file; do | |
| echo " • $file" | |
| done | |
| echo "" | |
| echo -e "${BLUE}Steps to resolve:${NC}" | |
| echo "1. Fix merge conflicts in the files above" | |
| echo "2. Run prettier on resolved files:" | |
| echo -e " ${GREEN}npx prettier --write <file>${NC}" | |
| echo "3. Stage the resolved files:" | |
| echo -e " ${GREEN}git add <file>${NC}" | |
| echo "4. Continue the rebase:" | |
| echo -e " ${GREEN}git rebase --continue${NC}" | |
| echo "" | |
| echo "The prettier script will continue to run after each commit." | |
| fi | |
| echo "" | |
| echo -e "${YELLOW}To abort and restore:${NC}" | |
| echo " git rebase --abort" | |
| echo " git checkout $BACKUP_BRANCH" | |
| fi | |
| # Clean up | |
| rm -f "$PRETTIER_SCRIPT" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment