git-plugin/skills/git-fork-workflow/SKILL.md
Fork management and upstream sync. Use when working with forks, syncing with upstream, detecting divergence, or preparing commits for contribution.
npx skillsauth add laurigates/claude-plugins git-fork-workflowInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expert guidance for managing forked repositories, synchronizing with upstream, and contributing back cleanly.
Run this first to detect the upstream remote, compute ahead/behind via
git rev-list, and get a recommended sync strategy (a pure function — it
runs no mutations):
bash "${CLAUDE_SKILL_DIR}/scripts/git-fork-workflow.sh" --home-dir "$HOME" --project-dir "$(pwd)"
Parse STATUS= and ISSUES: from the output. It emits IS_FORK,
UPSTREAM / ORIGIN, BEHIND / AHEAD (from
git rev-list --left-right --count upstream/main...origin/main), and
RECOMMENDED_STRATEGY (one of in-sync, fast-forward, ahead-only,
rebase, not-a-fork). The strategy is a recommendation only — executing
any destructive sync (reset, rebase, force-push) stays your call, per the
strategy prose below.
| Use this skill when... | Use git-upstream-pr instead when... |
|------------------------|-------------------------------------|
| Understanding fork remote architecture | Ready to submit a PR to upstream |
| Diagnosing fork divergence from upstream | Need step-by-step PR creation workflow |
| Syncing fork's main with upstream | Cherry-picking specific commits for upstream |
| Deciding on a sync strategy | Creating a cross-fork PR via gh CLI |
Forks use two remotes:
| Remote | Points To | Purpose |
|--------|-----------|---------|
| origin | Your fork (you/repo) | Push your work here |
| upstream | Original repo (owner/repo) | Pull updates from here |
# Verify remotes
git remote -v
# Add upstream if missing
git remote add upstream https://github.com/owner/original-repo.git
# Verify
git fetch upstream
git remote -v
# Check if upstream remote exists
git remote get-url upstream
# Get fork owner
git remote get-url origin | sed -E 's#.*github\.com[:/]##; s#\.git$##'
# Get upstream owner
git remote get-url upstream | sed -E 's#.*github\.com[:/]##; s#\.git$##'
When you squash-merge branches into your fork's main, the commit SHAs differ from upstream's commits. This creates divergence even when the code content is identical.
The data-gathering script (above) fetches both remotes and computes the
ahead/behind counts — read BEHIND and AHEAD from its output. To view the
specific divergent commits behind those counts:
# Show divergent commits
git log --oneline upstream/main..origin/main # Commits on fork not on upstream
git log --oneline origin/main..upstream/main # Commits on upstream not on fork
The script's BEHIND / AHEAD come from
git rev-list --left-right --count upstream/main...origin/main:
| BEHIND AHEAD | Meaning |
|--------|---------|
| 0 0 | Perfectly in sync |
| 5 0 | Fork is 5 behind upstream (upstream has 5 new commits) |
| 0 3 | Fork is 3 ahead (fork has 3 commits not on upstream) |
| 5 3 | Diverged: upstream has 5 new, fork has 3 unique |
# Syncs fork's default branch with upstream via GitHub API
gh repo sync owner/fork-repo
# Then pull locally
git pull origin main
Best when: fork has no unique commits worth preserving on main.
git fetch upstream
git merge --ff-only upstream/main
Best when: fork's main has not diverged. Fails cleanly if diverged (no messy merge commits).
git fetch upstream
git reset --hard upstream/main
git push --force-with-lease origin main
Best when: fork's main has diverged and you want to discard fork-only commits. Destructive - ensure no unique work is on main.
git fetch upstream
git rebase upstream/main
git push --force-with-lease origin main
Best when: fork has unique commits on main that should sit on top of upstream's history.
The script's RECOMMENDED_STRATEGY maps the BEHIND/AHEAD counts to a
strategy keyword via a pure function; use it as the starting point and confirm
against this table before running any destructive command:
| RECOMMENDED_STRATEGY | Situation | Strategy |
|---|-----------|----------|
| in-sync | 0 behind, 0 ahead | Nothing to do |
| fast-forward | Behind only, fork main clean | Fast-forward or gh repo sync |
| ahead-only | Ahead only, nothing to pull | No sync needed; fork leads upstream |
| rebase | Diverged, unique work worth keeping | Rebase (Strategy 4) |
| (diverged, work expendable) | Unique work expendable / match upstream exactly | Hard reset (Strategy 3) |
| (unsure) | Not sure | Try fast-forward first; it fails safely if diverged |
The recommendation never executes a sync — picking and running Strategy 3 (hard reset) or 4 (rebase + force-push) stays your decision.
Branch from upstream/main, not from your fork's main. This completely bypasses fork divergence:
git fetch upstream
git switch -c feat/my-contribution upstream/main
# Cherry-pick, code, or apply changes here
git push -u origin feat/my-contribution
# Create cross-fork PR targeting upstream
See git-upstream-pr for the complete workflow.
# Create PR from fork branch to upstream repo
gh pr create \
--repo owner/upstream-repo \
--base main \
--head your-username:feat/branch-name \
--title "feat: description" \
--body "PR description"
The --head must include the fork owner prefix (your-username:branch) when targeting a different repository.
# Has upstream remote = likely a fork
git remote get-url upstream 2>/dev/null && echo "Fork" || echo "Not a fork"
# Weekly sync routine
git fetch upstream
git switch main
git merge --ff-only upstream/main || echo "Diverged - manual sync needed"
git push origin main
git fetch upstream
git log --oneline origin/main..upstream/main
| Context | Command |
|---------|---------|
| Divergence count | git rev-list --left-right --count upstream/main...origin/main |
| Fork ahead commits | git log --oneline --format='%h %s' upstream/main..origin/main |
| Fork behind commits | git log --oneline --format='%h %s' origin/main..upstream/main |
| Quick sync check | git fetch upstream && git merge --ff-only upstream/main |
| Remote listing | git remote -v |
testing
Verify accumulated bug claims at upstream HEAD and dedup against trackers before filing issues. Use when filing upstream reports from backlogs, audit docs, or git-history findings.
documentation
Gate outward-bound text (upstream issues, docs, PR bodies) through isolated haiku fresh-reader critique before publishing. Use when an artifact must survive a reader with zero project context.
tools
Suggest improvements to SKILL.md content, descriptions, or tool config from eval results. Use when raising pass rates, fixing triggering, or iterating on a skill after evaluation.
tools
deadbranch CLI for stale-branch cleanup — dry-run preview, TUI or non-interactive delete, protects main/develop/WIP. Use when asked to clean up branches, prune branches, or remove stale branches.