Agent Skills: /git:upstream-pr

|

UncategorizedID: laurigates/claude-plugins/git-upstream-pr

Install this agent skill to your local

pnpm dlx add-skill https://github.com/laurigates/claude-plugins/tree/HEAD/git-plugin/skills/git-upstream-pr

Skill Files

Browse the full folder contents for git-upstream-pr.

Download Skill

Loading file tree…

git-plugin/skills/git-upstream-pr/SKILL.md

Skill Metadata

Name
git-upstream-pr
Description
|

/git:upstream-pr

Submit clean, atomic PRs to upstream repositories from fork work.

When to Use This Skill

| Use this skill when... | Use /git:commit instead when... | |------------------------|-----------------------------------| | Contributing changes back to the upstream repo | Committing to your own fork/repo | | Cherry-picking fork commits for upstream PR | Creating a PR within the same repo | | Fork's main has diverged from upstream | Fork and upstream are in sync | | Need a clean branch based on upstream/main | Working on a branch already tracking upstream |

Context

  • Current branch: !git branch --show-current
  • Git status: !git status --porcelain=v2 --branch
  • Remotes: !git remote -v
  • Has upstream: !git remote get-url upstream
  • Origin URL: !git remote get-url origin
  • Upstream URL: !git remote get-url upstream
  • Recent commits: !git log --oneline --max-count=20
  • Stash list: !git stash list

Parameters

Parse these from $ARGUMENTS:

| Parameter | Required | Description | |-----------|----------|-------------| | --commits sha1,sha2,... | No | Comma-separated commit SHAs to cherry-pick (interactive selection if omitted) | | --branch name | No | Name for the upstream PR branch (auto-generated if omitted) | | --upstream owner/repo | No | Override upstream repo (detected from remote if omitted) | | --draft | No | Create PR as draft | | --dry-run | No | Show what would happen without making changes |

Execution

Execute this fork-to-upstream PR workflow:

Step 1: Validate fork environment

  1. Verify this is a git repository: git rev-parse --git-dir
  2. Check if upstream remote exists (from context)
  3. If no upstream remote:
    • Try to detect via gh repo view --json parent -q '.parent.nameWithOwner'
    • If found, add it: git remote add upstream https://github.com/<owner/repo>.git
    • If not found, ask user with AskUserQuestion for the upstream repo URL
  4. Fetch upstream: git fetch upstream
  5. Record the current branch name and check for uncommitted changes
  6. If uncommitted changes exist, stash them: git stash push -m "upstream-pr: WIP before upstream PR"

Step 2: Assess fork state

Report the fork's divergence from upstream:

Fork status:
  Upstream: <upstream-repo>
  Behind upstream/main: N commits
  Ahead of upstream/main: M commits

If --dry-run is set, also show which commits would be selected and stop here.

Step 3: Select commits

If --commits provided:

  • Parse the comma-separated SHA list
  • Validate each SHA exists: git rev-parse --verify <sha>
  • Show summary of selected commits

If --commits not provided:

  • Show recent commits that are ahead of upstream/main:
    git log --oneline --format='%h %s (%cr)' upstream/main..HEAD
    
  • Use AskUserQuestion to let the user select which commits to include
  • Present commits as options with their subject lines

Step 4: Create clean branch from upstream/main

  1. Generate branch name if --branch not provided:
    • Extract scope from first commit message (e.g., feat(auth): add OAuth -> feat/auth-add-oauth)
    • Fallback: upstream-pr/<date>
  2. Create branch from upstream/main:
    git switch -c <branch-name> upstream/main
    

Step 5: Cherry-pick and squash

  1. Cherry-pick each selected commit in order:
    git cherry-pick <sha1> <sha2> ...
    
  2. If cherry-pick conflicts occur:
    • Report the conflict to the user
    • Reference git-conflicts for resolution
    • After resolution: git cherry-pick --continue
  3. Squash all cherry-picked commits into one atomic commit:
    git reset --soft upstream/main
    git commit -m "<conventional commit message>"
    
  4. Use AskUserQuestion to confirm or edit the commit message
    • Default message: derived from the cherry-picked commits
    • Format: conventional commit with scope

Step 6: Push to fork

git push -u origin <branch-name>

If --dry-run, show the command without executing.

Step 7: Create cross-fork PR

  1. Determine the upstream repo (from --upstream or detected remote)
  2. Determine the fork owner (from origin remote URL)
  3. Create the PR:
    gh pr create \
      --repo <upstream-owner/upstream-repo> \
      --base main \
      --head <fork-owner>:<branch-name> \
      --title "<conventional commit title>" \
      --body "<PR description>"
    
    Add --draft if the flag was provided.
  4. Report the PR URL to the user

Step 8: Restore working state

  1. Switch back to the original branch:
    git switch <original-branch>
    
  2. If changes were stashed in Step 1, pop them:
    git stash pop
    
  3. Report completion summary:
    Upstream PR created:
      PR: <url>
      Branch: <branch-name>
      Commits: N cherry-picked, squashed into 1
      Original branch restored: <branch>
    

Error Handling

| Error | Recovery | |-------|----------| | Cherry-pick conflict | Show conflicted files, reference git-conflicts skill | | Push rejected | Check if branch already exists on fork; suggest --branch override | | No upstream remote | Auto-detect from gh repo view --json parent or ask user | | Upstream/main not found | Try upstream/master; ask user for correct branch name | | No commits ahead of upstream | Report "Nothing to contribute" and exit |

Agentic Optimizations

| Context | Command | |---------|---------| | Divergence check | git rev-list --left-right --count upstream/main...HEAD | | Commits ahead | git log --oneline --format='%h %s' upstream/main..HEAD | | Validate SHA | git rev-parse --verify --short <sha> | | Fork owner | git remote get-url origin \| sed -E 's#.*github.com[:/]##; s#\.git$##; s#/.*##' | | Upstream repo | git remote get-url upstream \| sed -E 's#.*github.com[:/]##; s#\.git$##' | | Cross-fork PR | gh pr create --repo <upstream> --head <fork-owner>:<branch> |

Related Skills

/git:upstream-pr Skill | Agent Skills