| name | create-pr |
| description | Create a Pull Request from the current branch. Syncs upstream main/master, updates current branch, handles fork remotes intelligently, and generates PR title/description from diff and commits. Respects PR templates if present. REQUIRES Must be in a git repository with gh CLI available. |
Create PR Skill
Create a Pull Request from the current branch with intelligent remote detection and PR content generation.
Prerequisites Check (MUST verify first)
Before proceeding, verify:
git rev-parse --is-inside-work-tree
gh auth status
CURRENT_BRANCH=$(git branch --show-current)
DEFAULT_BRANCH=$(git remote show origin | grep 'HEAD branch' | cut -d' ' -f5)
if [ "$CURRENT_BRANCH" = "$DEFAULT_BRANCH" ]; then
echo "ERROR: Cannot create PR from default branch"
exit 1
fi
git status --porcelain
If checks fail, STOP and inform the user:
- Not in git repo → "This skill requires a git repository. Please navigate to a git project."
- gh not authenticated → "Please run
gh auth login first."
- On default branch → "You are on the default branch. Please checkout a feature branch first."
- Uncommitted changes → "You have uncommitted changes. Please commit or stash them first."
Input
The user may optionally provide:
- Target base branch (defaults to main/master)
- Draft mode flag
- Specific reviewers
Workflow
Step 1: Detect Repository Configuration
git remote -v
CURRENT_BRANCH=$(git branch --show-current)
DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef -q '.defaultBranchRef.name')
gh repo view --json owner,name,isFork,parent
Step 2: Identify Upstream and Fork Remotes
Determine the remote configuration:
git remote -v
IS_FORK=$(gh repo view --json isFork -q '.isFork')
if [ "$IS_FORK" = "true" ]; then
PARENT_OWNER=$(gh repo view --json parent -q '.parent.owner.login')
PARENT_NAME=$(gh repo view --json parent -q '.parent.name')
fi
Remote Classification Logic:
| Scenario | Upstream Remote | Push Remote |
|---|
| Single remote (origin) | origin | origin |
| Fork: origin=fork, upstream=parent | upstream | origin |
| Fork: origin=parent, fork remote exists | origin | fork remote |
| Multiple remotes, one is fork | non-fork remote | fork remote |
Detection Algorithm:
CURRENT_USER=$(gh api user -q '.login')
for remote in $(git remote); do
REMOTE_URL=$(git remote get-url $remote)
REMOTE_OWNER=$(echo "$REMOTE_URL" | sed -E 's/.*[:/]([^/]+)\/[^/]+\.git$/\1/' | sed 's/\.git$//')
if [ "$REMOTE_OWNER" = "$CURRENT_USER" ]; then
FORK_REMOTE=$remote
else
UPSTREAM_REMOTE=$remote
fi
done
UPSTREAM_REMOTE=${UPSTREAM_REMOTE:-origin}
FORK_REMOTE=${FORK_REMOTE:-origin}
Step 3: Sync Upstream Default Branch
git fetch $UPSTREAM_REMOTE $DEFAULT_BRANCH
git checkout $DEFAULT_BRANCH
git pull $UPSTREAM_REMOTE $DEFAULT_BRANCH
git checkout $CURRENT_BRANCH
Step 4: Update Current Branch with Upstream
git rebase $UPSTREAM_REMOTE/$DEFAULT_BRANCH
if [ $? -ne 0 ]; then
echo "Rebase failed. Please resolve conflicts manually."
git rebase --abort
exit 1
fi
Step 5: Push Branch to Remote
Check if branch exists on remote and push:
REMOTE_BRANCH_EXISTS=$(git ls-remote --heads $FORK_REMOTE $CURRENT_BRANCH | wc -l)
if [ "$REMOTE_BRANCH_EXISTS" -eq 0 ]; then
git push -u $FORK_REMOTE $CURRENT_BRANCH
else
git push --force-with-lease $FORK_REMOTE $CURRENT_BRANCH
fi
Important: Always use --force-with-lease instead of --force for safety.
Step 6: Gather PR Content Information
git log $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD --pretty=format:"%h %s%n%b" --no-merges
git diff --stat $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
git diff $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
git diff --name-only $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
Step 7: Check for PR Template
PR_TEMPLATE=""
for template_path in \
".github/pull_request_template.md" \
".github/PULL_REQUEST_TEMPLATE.md" \
"docs/pull_request_template.md" \
"PULL_REQUEST_TEMPLATE.md"; do
if [ -f "$template_path" ]; then
PR_TEMPLATE="$template_path"
break
fi
done
if [ -z "$PR_TEMPLATE" ] && [ -d ".github/PULL_REQUEST_TEMPLATE" ]; then
if [ -f ".github/PULL_REQUEST_TEMPLATE/default.md" ]; then
PR_TEMPLATE=".github/PULL_REQUEST_TEMPLATE/default.md"
fi
fi
if [ -n "$PR_TEMPLATE" ]; then
cat "$PR_TEMPLATE"
fi
Step 8: Generate PR Title and Description
Title Generation Rules:
- If single commit: Use commit message subject line
- If multiple commits: Summarize the overall change
- Follow conventional commit format if project uses it:
<type>(<scope>): <description>
- Keep under 72 characters
Description Generation:
If PR template exists, fill in the template sections:
| Common Template Section | How to Fill |
|---|
## Summary / ## Description | Summarize changes from commits and diff |
## Changes / ## What | List key changes from diff |
## Why / ## Motivation | Extract from commit bodies or infer from changes |
## Testing | List test files changed or suggest manual testing |
## Screenshots | Leave placeholder if UI changes detected |
## Checklist | Leave checkboxes for user to complete |
Fixes # / Closes # | Extract issue references from commits |
If no template, generate structured description:
## Summary
[2-3 sentences summarizing what this PR does]
## Changes
- [Key change 1]
- [Key change 2]
- [Key change 3]
## Testing
[How the changes were tested or should be tested]
---
[Any issue references found in commits]
Step 9: Create the Pull Request
if [ "$IS_FORK" = "true" ]; then
BASE_REPO="$PARENT_OWNER/$PARENT_NAME"
gh pr create \
--repo "$BASE_REPO" \
--base "$DEFAULT_BRANCH" \
--head "$CURRENT_USER:$CURRENT_BRANCH" \
--title "$PR_TITLE" \
--body "$PR_BODY"
else
gh pr create \
--base "$DEFAULT_BRANCH" \
--head "$CURRENT_BRANCH" \
--title "$PR_TITLE" \
--body "$PR_BODY"
fi
Use HEREDOC for body to preserve formatting:
gh pr create --title "$PR_TITLE" --body "$(cat <<'EOF'
## Summary
[Generated summary here]
## Changes
- Change 1
- Change 2
EOF
)"
Step 10: Report Results
After PR creation, provide:
gh pr view --json url,number,title,state
Output Format
PR Created Successfully
PR: #[NUMBER] - [TITLE]
URL: [PR_URL]
Base: [BASE_BRANCH] ← Head: [HEAD_BRANCH]
Remote: Pushed to [FORK_REMOTE]
Summary
[Brief description of what the PR contains]
Files Changed
| File | Changes |
|---|
path/to/file.ts | +[additions] -[deletions] |
Next Steps
Error Handling
| Situation | Action |
|---|
| No commits ahead of base | "No changes to create PR. Your branch is up to date with [base]." |
| Rebase conflicts | "Rebase failed due to conflicts. Please resolve manually and re-run." |
| Push rejected | "Push failed. Check if you have write access to the remote." |
| PR already exists | "A PR already exists for this branch: [URL]. Opening existing PR." |
| No remote access | "Cannot access remote. Check your authentication with gh auth status." |
| Fork detection failed | "Could not determine fork relationship. Please specify the target repo." |
Advanced Options
Draft PR
gh pr create --draft --title "$PR_TITLE" --body "$PR_BODY"
Add Reviewers
gh pr create --reviewer "user1,user2" --title "$PR_TITLE" --body "$PR_BODY"
Add Labels
gh pr create --label "enhancement,needs-review" --title "$PR_TITLE" --body "$PR_BODY"
Link to Issue
If commits reference issues (e.g., "Fixes #123"), automatically add to PR body:
ISSUES=$(git log $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD --pretty=format:"%B" | grep -oE "(Fixes|Closes|Resolves) #[0-9]+" | sort -u)
Important Notes
- Safety First: Always use
--force-with-lease instead of --force when pushing after rebase
- Fork Awareness: Automatically detect and handle fork workflows
- Template Respect: Always check for and use PR templates when available
- Conventional Commits: If project uses conventional commits, follow the format
- Issue Linking: Preserve issue references from commit messages
- Review Before Submit: Show generated title/description for user approval before creating PR