git-upstream-pr

v2026.09.24

Submit PRs to upstream repos from a fork — commit selection, squashing, cross-fork creation. Use when contributing changes upstream or cherry-picking fork commits.

GitHub
安装命令
npx skhub add laurigates/git-upstream-pr
Markdown
SKILL.md

/git:upstream-pr

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

When to Use This Skill

Use this skill when...Use something else instead when...
Contributing changes back to the upstream repoCommitting to your own fork/repo → /git:commit
Cherry-picking fork commits for upstream PR (single or multi-commit, squashing)Creating a PR within the same repo → /git:pr
Fork and upstream are roughly alignedFork has substantially diverged from upstream → /git:upstream-pr-diverged (patch-id eligibility, re-derive fallback, scrubbing)
Need a clean branch based on upstream/mainWorking 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 -v
  • Origin URL: !git remote -v
  • Upstream URL: !git remote -v
  • Recent commits: !git log --oneline --max-count=20
  • Stash list: !git stash list

Parameters

Parse these from $ARGUMENTS:

ParameterRequiredDescription
--commits sha1,sha2,...NoComma-separated commit SHAs to cherry-pick (interactive selection if omitted)
--branch nameNoName for the upstream PR branch (auto-generated if omitted)
--upstream owner/repoNoOverride upstream repo (detected from remote if omitted)
--draftNoCreate PR as draft
--dry-runNoShow 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

ErrorRecovery
Cherry-pick conflictShow conflicted files, reference git-conflicts skill
Push rejectedCheck if branch already exists on fork; suggest --branch override
No upstream remoteAuto-detect from gh repo view --json parent or ask user
Upstream/main not foundTry upstream/master; ask user for correct branch name
No commits ahead of upstreamReport "Nothing to contribute" and exit

Agentic Optimizations

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

Related Skills

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

Sep 24, 2026

分类

未分类

许可证

MIT

源路径

git-plugin/skills/git-upstream-pr

默认分支

main

最新提交

1668324

Tree SHA

b2d4cc3