# Sync

> Sync local repository with origin/main. Use before starting new work, after completing a PR, or when needing latest upstream changes. Safely stashes uncommitted changes, fetches and pulls origin/main, restores stash, and cleans up stale local branches (merged or with deleted remotes). Run from a linked git worktree, it syncs main in the primary checkout instead and removes the worktree once its branch is finished. Invoke when switching contexts or preparing for new feature work.

- Skill: `slamb2k/sync` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add slamb2k/sync`
- Raw SKILL.md: https://api.skillmd.com/api/skills/slamb2k/sync/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: slamb2k (https://skillmd.com/u/slamb2k)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/slamb2k/sync

---


# Sync - Repository Synchronization

When this skill is invoked, IMMEDIATELY output the banner below before doing anything else.
Pick ONE tagline at random — vary your choice each time.
CRITICAL: Reproduce the banner EXACTLY character-for-character, including the diagonal `/` glyph before the name.

```
{tagline}

       /$$ /$$$$$$  /$$     /$$ /$$   /$$  /$$$$$$ 
      /$$//$$__  $$|  $$   /$$/| $$$ | $$ /$$__  $$
     /$$/| $$  \__/ \  $$ /$$/ | $$$$| $$| $$  \__/
    /$$/ |  $$$$$$   \  $$$$/  | $$ $$ $$| $$      
   /$$/   \____  $$   \  $$/   | $$  $$$$| $$      
  /$$/    /$$  \ $$    | $$    | $$\  $$$| $$    $$
 /$$/    |  $$$$$$/    | $$    | $$ \  $$|  $$$$$$/
|__/      \______/     |__/    |__/  \__/ \______/ 
```

Taglines:
- 🎯 Pulling the latest moves...
- 🚂 All aboard the sync train!
- 🤝 Getting everyone on the same page!
- 📡 Fetching the latest plot twists!
- 🥷 Time to steal everyone else's code!
- ☕ Catching up on what you missed!
- 🔁 Rebase, merge, rinse, repeat!
- 🎬 Previously on main...

---

## Output Formatting

After the banner, display parsed input:
```
┌─ Input ────────────────────────────────────────
│  {Field}:  {value}
│  Flags:    {parsed flags or "none"}
└────────────────────────────────────────────────
```

Pre-flight results:
```
── Pre-flight ───────────────────────────────────
  ✅ {dep}           {version or "found"}
  ⚠️ {dep}           not found → {fallback detail}
  ❌ {dep}           missing → stopping
──────────────────────────────────────────────────
```

Stage/phase headers: `━━ {N} · {Name} ━━━━━━━━━━━━━━━━━━━━━━━━━`

Status icons: ✅ done · ❌ failed · ⚠️ degraded · ⏳ working · ⏭️ skipped

---

Synchronize local repository with the remote default branch using a
deterministic bash script — no LLM subagent needed since all steps are
pure git commands.

## Flags

Parse optional flags from the request:
- `--no-stash`: Don't auto-stash uncommitted changes
- `--no-cleanup`: Don't delete stale local branches
- `--no-rebase`: Use merge instead of rebase when on a feature branch

---

## Pre-flight

Before starting, check all dependencies in this table:

| Dependency | Type | Check | Required | Resolution | Detail |
|-----------|------|-------|----------|------------|--------|
| git | cli | `git --version` | yes | stop | Install from https://git-scm.com |

For each row, in order:
1. Run the Check command (for cli/npm) or test file existence (for agent/skill)
2. If found: continue silently
3. If missing: apply Resolution strategy
   - **stop**: notify user with Detail, halt execution
   - **url**: notify user with Detail (install link), halt execution
   - **install**: notify user, run the command in Detail, continue if successful
   - **ask**: notify user, offer to run command in Detail, continue either way (or halt if required)
   - **fallback**: notify user with Detail, continue with degraded behavior
4. After all checks: summarize what's available and what's degraded

---

## Pre-flight Detection

Before launching the subagent, detect the remote and default branch:

```
REMOTE=$(git remote | head -1)   # usually "origin"
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/$REMOTE/HEAD 2>/dev/null | sed 's|.*/||')
```

Fallback chain if `symbolic-ref` fails:
1. Check `git show-ref --verify refs/heads/main` → use `main`
2. Check `git show-ref --verify refs/heads/master` → use `master`
3. If neither exists, report error and stop

Pass `{REMOTE}` and `{DEFAULT_BRANCH}` into the subagent prompt.

---

## Execution

Run the sync script directly — no LLM subagent needed since all steps are
deterministic git commands:

```bash
# Resolve skill root (plugin install or direct install)
for SKILL_ROOT in \
  "${CLAUDE_PLUGIN_ROOT:-}" \
  "$HOME/.claude/plugins/marketplaces/slamb2k" \
  "$(dirname "$(readlink -f "$0")")/.."
do
  [ -f "$SKILL_ROOT/skills/sync/scripts/sync.sh" ] && break
done

bash "$SKILL_ROOT/skills/sync/scripts/sync.sh" \
  "{REMOTE}" "{DEFAULT_BRANCH}" {FLAGS}
```

Parse the output between `SYNC_REPORT_BEGIN` and `SYNC_REPORT_END` markers.
Extract `key=value` pairs for the report fields: `status`, `remote`,
`default_branch`, `main_updated_to`, `current_branch`, `worktree_mode`,
`stash`, `rebase`, `branches_cleaned`, `worktrees_skipped`, `errors`. When
`worktree_mode=true`, three more fields appear right after it:
`primary_path` (the repo's main checkout), `worktree_removed` (the removed
worktree's path, `skipped (<reason>)`, or `none`), and `main_sync`
(`updated`, `already up to date`, or `skipped (<reason>)` — whether main was
pulled in the primary).

Branch cleanup also tears down associated worktrees: a branch is "finished"
when it's merged, its remote is gone, OR its PR is closed without merging
(pr-first-autonomous-build.md REQ-014) — checked via a bounded `gh`/`az`
PR-state lookup, once per live worktree, not once per local branch. A
finished branch's worktree is removed before the branch is deleted, whether
or not it carries a `.mad-skills-auto` sentinel — that sentinel is no longer
written by `/speccy` (see `references/autonomous-worktree-lifecycle.md`,
repo root), so most `/build`-owned worktrees are sentinel-less by default.
A worktree with uncommitted changes is never force-removed — it and its
branch are left intact and reported in `worktrees_skipped`.

**Run from a linked worktree**, the script auto-detects this (no flag
needed) and behaves differently: it syncs main in the primary checkout
rather than checking it out locally, then — if this worktree's branch is
finished (merged or its upstream is gone) and the worktree is clean — removes
the worktree and deletes the branch. A dirty finished worktree is left alone
(`worktree_removed=skipped (dirty)`); an unfinished branch is rebased in
place as usual. `--no-cleanup` skips the removal but still syncs main.
Branch deletion falls back to git's force delete (`-D`) only when the
branch's upstream is confirmed gone (the squash-merge case); a
force-deleted branch tip is not lost — it remains reflog-recoverable
(`git reflog`, `git fsck --lost-found`) until git's normal reflog expiry.

**Session return (worktree mode).** If the report shows
`worktree_removed=<path>` (an actual path, not `none` or a `skipped …`
reason), the session's cwd no longer exists — the worktree was just removed.
Before running any further git commands, return to `primary_path`: use the
native `ExitWorktree` tool if the session entered this worktree via
`EnterWorktree` and the tool is available; otherwise, run the next Bash
command with `cd "<primary_path>"` first.

Exit codes: 0=success, 1=fatal error, 2=partial success (conflict warnings).

---

## Report to User

Parse the subagent's SYNC_REPORT and present a clean summary:

```
┌─ Sync · Report ────────────────────────────────
│
│  ✅ Sync complete
│
│  🌿 Main:     {commit} — {message}
│  🔀 Branch:   {current_branch}
│  📦 Stash:    {restored|none|conflict}
│  🧹 Cleaned:  {branches or "none"}
│
└─────────────────────────────────────────────────
```

If errors occurred:
```
│  ❌ {error description}
│     {suggested resolution}
```

