cz-base / git-sync-guide.md
james-d-taboola's picture
docs: add git sync up guide
1062869

A newer version of the Gradio SDK is available: 6.8.0

Upgrade

Git Sync Guide: Merging Local Branch to Multiple Remotes

This guide documents the process for merging a local branch to multiple remote repositories and pushing the changes.

Overview

When working with multiple remote repositories (like different deployment environments), you may need to sync your local changes to all of them. This guide shows how to merge a local branch to multiple remote main branches safely.

HuggingFace Space Configuration

Each HuggingFace space copy uses identical code with only these differences:

  1. README.md - Different titles/descriptions to distinguish spaces on HuggingFace
  2. Environment Variable appName - Determines which configuration to use:
    • NCSLM_LPD - Uses config from NCSLM_LPD/assistant_config.py
    • SEL - Uses config from SEL/assistant_config.py
    • SEL_COACH - Uses config from SEL_COACH/assistant_config.py

This allows multiple deployments of the same application with different behaviors/configurations while maintaining a single codebase.

Branching Strategy

Our development workflow follows a structured branching strategy:

Deployment Flow

main (local development)
  ↓
  β”œβ”€β”€ origin-sel/main (main-sel)
  └── origin-sel-coach/main (main-sel-coach)
origin-sel/main (main-sel)
  ↓
  β”œβ”€β”€ origin-sel-ch1/main
  β”œβ”€β”€ origin-sel-ch2/main
  └── origin-sel-ch3/main

Complete Workflow

  1. Development Phase: Work and commit changes in main branch
  2. Deployment Phase: Merge main into:
    • origin-sel/main (tracked as main-sel locally)
    • origin-sel-coach/main (tracked as main-sel-coach locally)
  3. Deployment Phase 2: Use origin-sel/main (main-sel) to sync to channel remotes: (these copies are for concurrent use cases)
    • origin-sel-ch1/main
    • origin-sel-ch2/main
    • origin-sel-ch3/main

Prerequisites

  • Git repository with multiple configured remotes
  • Local branch with changes to sync
  • Write access to all target remotes

Process Workflow

1. Check Current Status

First, verify your current branch and git status:

git status
git branch -a

2. Fetch Latest Changes

Update all remote tracking branches:

git fetch origin-sel && git fetch origin-sel-coach
git fetch origin-sel-ch1 && git fetch origin-sel-ch2 && git fetch origin-sel-ch3

3. Merge to Each Remote (Repeat for each target remote)

For each remote repository, follow these steps:

Step 3.1: Create Local Tracking Branch

git checkout -B <local-branch-name> <remote>/<target-branch>

Example:

git checkout -B origin-sel-ch1-main origin-sel-ch1/main

What this does:

  • -B flag creates a new branch or resets existing one
  • Creates local branch tracking the remote branch
  • Switches to the newly created branch

Step 3.2: Merge Your Local Branch

git merge <your-local-branch> --no-ff -m "Merge <your-local-branch> into <remote>/<target-branch>"

Example:

git merge main-sel --no-ff -m "Merge main-sel into origin-sel-ch1/main"

What this does:

  • --no-ff creates a merge commit even if fast-forward is possible
  • -m adds a descriptive commit message
  • Merges your changes into the remote branch

Step 3.3: Push to Remote

git push <remote> <local-tracking-branch>:<target-branch>

Example:

git push origin-sel-ch1 origin-sel-ch1-main:main

Complete Example

Deployment Phase: Sync from main to variant remotes

First, sync your local main branch to the variant remotes:

# Fetch latest changes from variant remotes
git fetch origin-sel && git fetch origin-sel-coach

# Sync to origin-sel/main (main-sel)
git checkout -B main-sel origin-sel/main
git merge main --no-ff -m "Merge main into origin-sel/main"
git push origin-sel main-sel:main

# Sync to origin-sel-coach/main (main-sel-coach)
git checkout -B main-sel-coach origin-sel-coach/main
git merge main --no-ff -m "Merge main into origin-sel-coach/main"
git push origin-sel-coach main-sel-coach:main

# Return to main branch
git checkout main

Deployment Phase 2: Sync from main-sel to channel remotes

Here's a complete example for syncing main-sel branch to three remotes:

# Switch to main-sel branch
git checkout main-sel

# Fetch latest changes
git fetch origin-sel-ch1 && git fetch origin-sel-ch2 && git fetch origin-sel-ch3

# Sync to origin-sel-ch1
git checkout -B origin-sel-ch1-main origin-sel-ch1/main
git merge main-sel --no-ff -m "Merge main-sel into origin-sel-ch1/main"
git push origin-sel-ch1 origin-sel-ch1-main:main

# Sync to origin-sel-ch2
git checkout -B origin-sel-ch2-main origin-sel-ch2/main
git merge main-sel --no-ff -m "Merge main-sel into origin-sel-ch2/main"
git push origin-sel-ch2 origin-sel-ch2-main:main

# Sync to origin-sel-ch3
git checkout -B origin-sel-ch3-main origin-sel-ch3/main
git merge main-sel --no-ff -m "Merge main-sel into origin-sel-ch3/main"
git push origin-sel-ch3 origin-sel-ch3-main:main

Cleanup

After successful sync, clean up temporary branches:

# Return to original branch
git checkout main-sel

# Delete temporary tracking branches
git branch -D origin-sel-ch1-main origin-sel-ch2-main origin-sel-ch3-main

Key Commands Explained

Command Purpose
git checkout -B Create/reset local branch and switch to it
git merge --no-ff Create explicit merge commit
git push remote local:remote Push local branch to remote branch
git branch -D Force delete local branches

Safety Tips

  1. Always fetch first - Ensure you have latest remote changes
  2. Use --no-ff - Creates clear merge history
  3. Descriptive commit messages - Document what you're merging
  4. Clean up afterwards - Remove temporary branches
  5. Test in one remote first - If unsure, test the process with one remote

Troubleshooting

Merge Conflicts

If you encounter merge conflicts:

# Resolve conflicts in your editor
git add <resolved-files>
git commit -m "Resolve merge conflicts"
git push <remote> <local-branch>:<target-branch>

Failed Push

If push fails due to remote changes:

git fetch <remote>
git merge <remote>/<target-branch>
# Resolve any conflicts
git push <remote> <local-branch>:<target-branch>

Undo Last Merge (if not pushed yet)

git reset --hard HEAD~1

Alternative: Automation Scripts

For frequent use, you can create automation scripts:

Script 1: Deployment Phase (main β†’ variant)

Create sync-to-variant.sh:

#!/bin/bash
LOCAL_BRANCH=${1:-main}
echo "Syncing $LOCAL_BRANCH to variant remotes..."

# Fetch latest changes from variant remotes
git fetch origin-sel && git fetch origin-sel-coach

# Sync to origin-sel/main (main-sel)
echo "Syncing to origin-sel/main..."
git checkout -B main-sel origin-sel/main
git merge $LOCAL_BRANCH --no-ff -m "Merge $LOCAL_BRANCH into origin-sel/main"
git push origin-sel main-sel:main

# Sync to origin-sel-coach/main (main-sel-coach)
echo "Syncing to origin-sel-coach/main..."
git checkout -B main-sel-coach origin-sel-coach/main
git merge $LOCAL_BRANCH --no-ff -m "Merge $LOCAL_BRANCH into origin-sel-coach/main"
git push origin-sel-coach main-sel-coach:main

# Return to original branch
git checkout $LOCAL_BRANCH
echo "variant sync complete!"

Usage: ./sync-to-variant.sh or ./sync-to-variant.sh main

Script 2: Deployment Phase 2 (main-sel β†’ channels)

Create sync-to-channels.sh:

#!/bin/bash
LOCAL_BRANCH=${1:-main-sel}
REMOTES=("origin-sel-ch1" "origin-sel-ch2" "origin-sel-ch3")

echo "Syncing $LOCAL_BRANCH to channel remotes..."

# Switch to source branch
git checkout $LOCAL_BRANCH

# Fetch latest changes
git fetch origin-sel-ch1 && git fetch origin-sel-ch2 && git fetch origin-sel-ch3

for remote in "${REMOTES[@]}"; do
    echo "Syncing to $remote..."
    git checkout -B ${remote}-main ${remote}/main
    git merge $LOCAL_BRANCH --no-ff -m "Merge $LOCAL_BRANCH into $remote/main"
    git push $remote ${remote}-main:main
done

git checkout $LOCAL_BRANCH
git branch -D origin-sel-ch1-main origin-sel-ch2-main origin-sel-ch3-main
echo "Channel sync complete!"

Usage: ./sync-to-channels.sh or ./sync-to-channels.sh main-sel

Script 3: Complete Deployment (both phases)

Create full-deploy.sh:

#!/bin/bash
LOCAL_BRANCH=${1:-main}

echo "=== Starting Full Deployment ==="
echo "Phase 1: Syncing $LOCAL_BRANCH to variant remotes..."

# Phase 1: Sync to variant
./sync-to-variant.sh $LOCAL_BRANCH

echo "Phase 2: Syncing main-sel to channel remotes..."

# Phase 2: Sync to channels
./sync-to-channels.sh main-sel

echo "=== Full Deployment Complete ==="

Usage: ./full-deploy.sh or ./full-deploy.sh main

Setup Instructions

  1. Create the scripts:
chmod +x sync-to-variant.sh sync-to-channels.sh full-deploy.sh
  1. Place them in your project root or add to your PATH

  2. Run as needed:

    • Individual phases: ./sync-to-variant.sh β†’ ./sync-to-channels.sh
    • Complete deployment: ./full-deploy.sh