---
name: step-sync
description: Sync with remote and rebase if behind
next_step: null
---

# Step: SYNC - Synchronize with Remote

## YOUR TASK:

Fetch from remote, detect divergence, push local commits, and rebase if behind base branch.

**ULTRA THINK about merge conflicts.**

---

## EXECUTION SEQUENCE:

### 1. Fetch Remote State

```bash
git fetch origin --quiet
CURRENT=$(git rev-parse --abbrev-ref HEAD)

# Determine base branch
case "$CURRENT" in
  feature/*) BASE_BRANCH="develop" ;;
  release/*) BASE_BRANCH="develop" ;;
  hotfix/*)  BASE_BRANCH="main" ;;
  *)         BASE_BRANCH="develop" ;;
esac
```

### 2. Analyze Divergence

```bash
# Current branch vs remote
AHEAD=$(git rev-list --count origin/$CURRENT..HEAD 2>/dev/null || echo "0")
BEHIND=$(git rev-list --count HEAD..origin/$CURRENT 2>/dev/null || echo "0")

# Current branch vs base branch
BASE_AHEAD=$(git rev-list --count origin/$BASE_BRANCH..HEAD 2>/dev/null || echo "0")
BASE_BEHIND=$(git rev-list --count HEAD..origin/$BASE_BRANCH 2>/dev/null || echo "0")
```

**State matrix:**

| Ahead | Behind | State | Action |
|-------|--------|-------|--------|
| 0 | 0 | Synced | Nothing to do |
| >0 | 0 | Ahead | Push |
| 0 | >0 | Behind | Pull |
| >0 | >0 | Diverged | Pull --rebase + Push |

### 3. Display Status

```
Sync Status: {CURRENT}

| Remote | Ahead | Behind | Status |
|--------|-------|--------|--------|
| origin/{CURRENT} | {AHEAD} | {BEHIND} | {state} |
| origin/{BASE_BRANCH} | {BASE_AHEAD} | {BASE_BEHIND} | {state} |
```

### 4. Push Local Commits

See [references/sync-push-verify.md](../references/sync-push-verify.md) for push with verification.

### 5. Pull Remote Commits

```bash
[ "$BEHIND" -gt 0 ] && {
  echo "Pulling $BEHIND commit(s) from origin/$CURRENT..."

  # Check for uncommitted changes
  DIRTY=$(git status --porcelain | wc -l)
  [ "$DIRTY" -gt 0 ] && {
    git stash push -m "sync-stash-$(date +%s)"
    STASHED=true
  }

  git pull --rebase origin $CURRENT

  [ "$STASHED" = true ] && git stash pop
}
```

### 6. Rebase on Base Branch (if behind)

```bash
[ "$BASE_BEHIND" -gt 0 ] && {
  echo "Branch is $BASE_BEHIND commits behind $BASE_BRANCH"

  if [ "$auto_mode" = true ]; then
    # Auto rebase
    git rebase origin/$BASE_BRANCH
  else
    # Ask user
    AskUserQuestion:
      header: "Rebase"
      question: "Rebase on $BASE_BRANCH? ($BASE_BEHIND commits behind)"
      options:
        - label: "Yes (Recommended)"
          description: "Rebase to include latest changes"
        - label: "No"
          description: "Keep current base"
  fi
}
```

### 7-8. Handle Rebase Conflicts and Force Push

See [references/sync-rebase-conflicts.md](../references/sync-rebase-conflicts.md) for:
- Conflict detection and migration conflict handling
- User options (resolve, abort, accept theirs)

See [references/sync-push-verify.md](../references/sync-push-verify.md) for force push with verification.

### 9. Summary

```
╔══════════════════════════════════════════════════════════════════╗
║                    SYNC COMPLETE                                  ║
╠══════════════════════════════════════════════════════════════════╣
║  Branch: {CURRENT}                                                ║
╠══════════════════════════════════════════════════════════════════╣
║  Actions:                                                         ║
║  {✅ Pushed {N} commits | ⬜ Nothing to push}                     ║
║  {✅ Pulled {N} commits | ⬜ Nothing to pull}                     ║
║  {✅ Rebased on {BASE_BRANCH} | ⬜ No rebase needed}              ║
╠══════════════════════════════════════════════════════════════════╣
║  Status: In sync with remote                                      ║
╠══════════════════════════════════════════════════════════════════╣
║  NEXT: /gitflow pr                                                ║
╚══════════════════════════════════════════════════════════════════╝
```

---

## ERROR HANDLING:

| Error | Solution |
|-------|----------|
| Push rejected | Pull first, then push |
| Rebase conflict | Resolve or abort |
| Migration conflict | Use /efcore rebase-snapshot |
| Force push blocked | Check branch protection |

---

## SUCCESS CRITERIA:

- All local commits pushed
- All remote commits pulled
- Rebased on base branch (if needed)
- No conflicts remaining

## NEXT STEP:

User runs `/gitflow pr` to create pull request.
