git-upstream-pr-diverged
Submit a diverged-fork commit to upstream as a clean PR via cherry-pick with re-derive fallback, message scrubbing, and regression checks. Use when direct rebase fails.
What this skill does
# /git:upstream-pr-diverged
Submit a single commit from a heavily-diverged fork back to upstream as a clean, regression-free PR. The simpler `/git:upstream-pr` covers aligned-fork cherry-picks; this skill handles the case where direct rebase fails.
## When to Use This Skill
| Use this skill when... | Use `/git:upstream-pr` instead when... |
|------------------------|----------------------------------------|
| Fork has substantially diverged from upstream | Fork and upstream are roughly aligned |
| Cherry-pick may produce many conflicts on shared modules | Single commit applies cleanly |
| You need patch-id matching for already-applied content | You want a quick cherry-pick + cross-fork PR |
| The change touches files that may be fork-only | All touched files exist upstream |
| The PR needs commit-message scrubbing (fork issue refs, Claude trailers) | Commit messages are already upstream-clean |
| Pre-flight regression check against upstream baseline matters | The change is trivial enough to skip pre-flight |
## Configuration
Per-project configuration lives at `.claude/upstream-pr.local.md` (gitignored). All fields are optional; sensible defaults apply.
```markdown
---
upstream_remote: upstream
upstream_repo: owner/repo
branch_prefix: pr-upstream/
linter_cmd: uv run ruff check
test_cmd: uv run pytest -q
pr_body_template_path: docs/UPSTREAM_PR_TEMPLATE.md
---
# Notes
Free-form notes — fork drift hotspots, files to never touch upstream, etc.
```
| Field | Default | Used by |
|-------|---------|---------|
| `upstream_remote` | `upstream` | All scripts |
| `upstream_repo` | Parsed from `git remote get-url <upstream_remote>` | `gh pr create --repo` |
| `branch_prefix` | `pr-upstream/` | Branch name in `prepare-branch.sh` |
| `linter_cmd` | (empty — pre-flight skipped) | Pre-flight stash-roundtrip |
| `test_cmd` | (empty — pre-flight skipped) | Pre-flight stash-roundtrip |
| `pr_body_template_path` | (empty — built-in template) | PR body |
Add `.claude/*.local.md` to `.gitignore`.
## Context
- Current branch: !`git branch --show-current`
- Working tree: !`git status --porcelain=v2 --branch`
- Remotes: !`git remote -v`
- Config file: !`find .claude -maxdepth 1 -name 'upstream-pr.local.md'`
## Parameters
Parse from `$ARGUMENTS`:
| Parameter | Required | Description |
|-----------|----------|-------------|
| `<sha>` | Yes | Commit SHA on the fork to send upstream |
| `--topic <slug>` | No | Topic slug for branch name; auto-derived from commit subject if omitted |
## Execution
Execute this upstream-PR workflow:
### Step 1: Check eligibility
Run the eligibility check before touching any branch:
```bash
bash "${CLAUDE_SKILL_DIR}/scripts/check-eligibility.sh" <sha>
```
Exit codes drive next steps:
| Exit | Meaning | Action |
|------|---------|--------|
| `0` | Every touched file exists upstream and content is novel | Proceed to Step 2 |
| `1` | At least one fork-only file | Stop. Tell the user the change isn't standalone-PR-able; predecessor feature must land first |
| `3` | Content already applied upstream under a different SHA | Stop. Report the matching upstream commit; nothing to PR |
The patch-id check (`git patch-id --stable`) catches re-applied content from maintainer re-merges or squashes — even when the SHA differs.
### Step 2: Prepare the branch
Derive a topic slug from the commit subject if `--topic` was not provided. Then:
```bash
bash "${CLAUDE_SKILL_DIR}/scripts/prepare-branch.sh" <topic-slug> <sha>
```
The script:
1. Verifies a clean working tree
2. Re-runs the eligibility check
3. Fetches the upstream remote
4. Creates `<branch_prefix><topic-slug>` from `<upstream_remote>/main` (or `/master`)
5. Cherry-picks `<sha>`
6. Reports any conflict files
### Step 3: Resolve conflicts (if any)
When the cherry-pick produces conflicts, **preserve upstream's surrounding shape**, not the fork's. The goal is the smallest readable diff against upstream — a maintainer must see the change make sense in upstream's current code, not in the fork's.
#### When to abort and re-derive
If the cherry-pick produces dozens of conflict blocks across multiple files (typical when upstream and fork have drifted heavily on shared modules), abort and re-derive instead of fighting hunks:
```bash
git cherry-pick --abort
git checkout -b <branch> <upstream_remote>/main
# Re-apply the change against upstream's actual current files.
```
Re-derive is the right call when:
- The original commit is a **mechanical, re-applicable transform** (e.g. `print()` → logging, deprecation rename, lint-rule auto-fixes) — the rules transfer cleanly even if line numbers don't.
- Upstream's version of the file has **additional lines the fork removed** — re-derive lets you cover them with the same heuristic rather than rationalizing missing hunks.
- The cherry-pick conflict count exceeds roughly **20 blocks across >2 files**.
Heuristic: extract the original commit's `before → after` map (e.g. `git show <sha> | grep -E '^[-+].*pattern'`) and use it as the rulebook when re-applying against upstream. The PR body should disclose the re-derive (see template below).
### Step 4: Pre-flight regression check
For refactor / cleanup PRs, verify lint and test parity against the **pristine upstream baseline**, not against the fork. This catches stray formatter touches, accidental import reordering, and indentation drift from Edit-tool replacements.
If `linter_cmd` and `test_cmd` are configured, run a stash roundtrip:
```bash
# Baseline (pristine upstream):
git stash push -- <changed-files>
<linter_cmd> <changed-files> 2>&1 | tail -1 # error count
<test_cmd> 2>&1 | tail -1 # pass count
git stash pop
# After (with your changes): run the same two commands and compare.
```
Both numbers must match (or improve). Quote both in the PR body's "Testing Performed" section.
For Python files, also run `python3 -c "import ast; ast.parse(open(F).read())"` on every edited file — catches indentation breaks that ruff might miss on already-warning-laden upstream code.
### Step 5: Scrub the commit message
Run the scrub helper:
```bash
bash "${CLAUDE_SKILL_DIR}/scripts/scrub-commit.sh" --check
```
If violations are reported, run without `--check` to amend interactively:
```bash
bash "${CLAUDE_SKILL_DIR}/scripts/scrub-commit.sh"
```
The scrub rules:
- **Strip local issue references** — `Closes #74`, `Addresses #19`, etc. point at the fork's tracker, not upstream's.
- **Strip Claude trailers** — `Co-authored-by: Claude ...`, `Generated with [Claude Code]`. Upstream doesn't follow that convention.
- **Soften fork-specific tooling** — if the body cites a tool upstream doesn't run (`bandit B607`, `ty`, `vulture`), describe the underlying problem instead.
- **Keep the conventional-commit prefix** — `fix(security):`, `feat(parser):`, etc.
The amend wraps `git commit --amend` with `PRE_COMMIT_ALLOW_NO_CONFIG=1` because upstream may have no `.pre-commit-config.yaml` and a locally-installed pre-commit hook would otherwise refuse the commit.
### Step 6: Verify diff hygiene
Before pushing, verify with:
```bash
git diff <upstream_remote>/main..HEAD
```
Every hunk should be defensible to a maintainer who has never seen the fork.
- Don't bundle formatter cleanups with the fix. Keep upstream's existing import order even if the fork's linter would reformat. Upstream may have unusual indentation (e.g. 21-space rather than 20-space blocks) — preserve it; Edit-tool replacements that change leading whitespace by even one character will break the parse.
- One commit per PR. If the cherry-pick produced multiple commits, squash before pushing.
### Step 7: Push and open the PR
```bash
git push origin <branch>
gh pr create --repo <upstream_repo> --base main \
--head <fork-owner>:<branch> \
--title "<conventional-commit subject>" \
--body "<see body template below>"
```
If `pr_body_template_path` is configured, use that template; otherwise use the built-in template:
```markdownRelated in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.