- Check if directory is a git repository before proceeding - Add fallback for git switch (use checkout if switch fails) - Handle offline/no-origin scenarios gracefully - Use local HEAD instead of origin/main for comparison - Add error handling for push operations - Continue backup locally if remote push fails
110 lines
3.1 KiB
Bash
Executable File
110 lines
3.1 KiB
Bash
Executable File
#!/bin/bash
|
|
# Backup main branch with smart duplicate detection
|
|
|
|
set -e # Exit on any error
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
NC='\033[0m' # No Color
|
|
|
|
echo -e "${GREEN}🔄 Starting main branch backup...${NC}"
|
|
|
|
# Function to backup a single repository
|
|
backup_repo() {
|
|
local repo_path=$1
|
|
local repo_name=$(basename "$repo_path")
|
|
|
|
echo -e "\n${YELLOW}Processing repository: $repo_name${NC}"
|
|
|
|
cd "$repo_path"
|
|
|
|
# Check if this is a git repository
|
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
|
echo -e "${RED}❌ $repo_name: Not a git repository!${NC}"
|
|
cd ..
|
|
return 1
|
|
fi
|
|
|
|
# Ensure we're on main
|
|
CURRENT_BRANCH=$(git branch --show-current 2>/dev/null || echo "")
|
|
if [ "$CURRENT_BRANCH" != "main" ]; then
|
|
echo "Switching to main branch..."
|
|
git switch main 2>/dev/null || git checkout main
|
|
fi
|
|
|
|
# Pull latest changes
|
|
echo "Pulling latest changes..."
|
|
if ! git pull origin main 2>/dev/null; then
|
|
echo -e "${YELLOW}⚠️ Could not pull latest changes (might be offline or no origin/main)${NC}"
|
|
# Continue anyway with local state
|
|
fi
|
|
|
|
# Check if working directory is clean
|
|
if [ -n "$(git status --porcelain)" ]; then
|
|
echo -e "${RED}⚠️ Working directory not clean in $repo_name!${NC}"
|
|
echo "Skipping backup for this repository"
|
|
cd ..
|
|
return 1
|
|
fi
|
|
|
|
# Check if backup is needed
|
|
LATEST_BACKUP=$(git branch -r --sort=-committerdate 2>/dev/null | grep "origin/backup/main-" | head -1 | cut -d'/' -f2 || true)
|
|
|
|
if [ -n "$LATEST_BACKUP" ]; then
|
|
MAIN_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "")
|
|
BACKUP_COMMIT=$(git rev-parse origin/$LATEST_BACKUP 2>/dev/null || echo "")
|
|
|
|
if [ -n "$MAIN_COMMIT" ] && [ "$MAIN_COMMIT" = "$BACKUP_COMMIT" ]; then
|
|
echo -e "${GREEN}✅ $repo_name: Already backed up in $LATEST_BACKUP${NC}"
|
|
cd ..
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Create new backup
|
|
BACKUP_BRANCH="backup/main-$(date +%Y-%m-%d-%H%M%S)"
|
|
|
|
echo "Creating backup branch: $BACKUP_BRANCH"
|
|
git checkout -b $BACKUP_BRANCH
|
|
|
|
# Try to push, but continue even if it fails
|
|
if git push -u origin $BACKUP_BRANCH 2>/dev/null; then
|
|
echo -e "${GREEN}✅ Backup pushed to remote${NC}"
|
|
else
|
|
echo -e "${YELLOW}⚠️ Could not push backup to remote (backup exists locally only)${NC}"
|
|
fi
|
|
|
|
git checkout main
|
|
|
|
echo -e "${GREEN}✅ $repo_name: Backup created successfully${NC}"
|
|
|
|
# Cleanup old backups (keep last 7)
|
|
for branch in $(git branch -r --sort=-committerdate 2>/dev/null | grep "origin/backup/main-" | tail -n +8); do
|
|
BACKUP_NAME=$(echo $branch | cut -d'/' -f2)
|
|
echo "Deleting old backup: $BACKUP_NAME"
|
|
git push origin --delete $BACKUP_NAME 2>/dev/null || true
|
|
done
|
|
|
|
cd ..
|
|
}
|
|
|
|
# Backup all repositories
|
|
REPOS=(
|
|
"/Users/sd9235/code/mygh/learning_ai_common_plat"
|
|
"/Users/sd9235/code/mygh/learning_voice_ai_agent"
|
|
"/Users/sd9235/code/mygh/learning_multimodal_memory_agents"
|
|
)
|
|
|
|
# Check which repos exist
|
|
for repo in "${REPOS[@]}"; do
|
|
if [ -d "$repo" ]; then
|
|
backup_repo "$repo"
|
|
else
|
|
echo -e "${YELLOW}Repository not found: $repo${NC}"
|
|
fi
|
|
done
|
|
|
|
echo -e "\n${GREEN}✨ Backup process completed!${NC}"
|