create-pr
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseCreate PR Skill
创建PR技能
Create a Pull Request from the current branch with intelligent remote detection and PR content generation.
从当前分支创建Pull Request,具备智能远程仓库检测和PR内容生成功能。
Prerequisites Check (MUST verify first)
前置条件检查(必须首先验证)
Before proceeding, verify:
bash
undefined在继续操作前,请验证以下内容:
bash
undefined1. Check if in a git repository
1. 检查是否处于git仓库中
git rev-parse --is-inside-work-tree
git rev-parse --is-inside-work-tree
2. Check if gh CLI is available and authenticated
2. 检查gh CLI是否可用且已完成认证
gh auth status
gh auth status
3. Check current branch is not main/master
3. 检查当前分支是否为main/master
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
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
4. Check for uncommitted changes (warn user if any)
4. 检查是否存在未提交的更改(如果有则向用户发出警告)
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."git status --porcelain
如果检查不通过,请停止操作并告知用户:
- 不在git仓库中 → "该技能需要在git仓库环境中使用,请切换到git项目目录下。"
- gh未认证 → "请先执行`gh auth login`命令。"
- 当前为默认分支 → "你当前处于默认分支,请先切换到功能分支。"
- 存在未提交的更改 → "你有未提交的更改,请先提交或暂存这些更改。"Input
输入参数
The user may optionally provide:
- Target base branch (defaults to main/master)
- Draft mode flag
- Specific reviewers
用户可选择提供以下参数:
- 目标基准分支(默认为main/master)
- 草稿模式标记
- 指定审核人员
Workflow
工作流程
Step 1: Detect Repository Configuration
步骤1:检测仓库配置
bash
undefinedbash
undefinedGet all remotes
获取所有远程仓库
git remote -v
git remote -v
Get current branch name
获取当前分支名称
CURRENT_BRANCH=$(git branch --show-current)
CURRENT_BRANCH=$(git branch --show-current)
Detect default branch (main or master)
检测默认分支(main或master)
DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef -q '.defaultBranchRef.name')
DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef -q '.defaultBranchRef.name')
Get repository info
获取仓库信息
gh repo view --json owner,name,isFork,parent
undefinedgh repo view --json owner,name,isFork,parent
undefinedStep 2: Identify Upstream and Fork Remotes
步骤2:识别上游和Fork远程仓库
Determine the remote configuration:
bash
undefined确定远程仓库配置:
bash
undefinedList all remotes with their URLs
列出所有远程仓库及其URL
git remote -v
git remote -v
Check if this repo is a fork
检查当前仓库是否为Fork
IS_FORK=$(gh repo view --json isFork -q '.isFork')
IS_FORK=$(gh repo view --json isFork -q '.isFork')
If it's a fork, get parent info
如果是Fork仓库,获取父仓库信息
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**:
```bashif [ "$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
**远程仓库分类逻辑**:
| 场景 | 上游远程仓库 | 推送远程仓库 |
|----------|-----------------|-------------|
| 单个远程仓库(origin) | origin | origin |
| Fork仓库:origin=Fork,upstream=父仓库 | upstream | origin |
| Fork仓库:origin=父仓库,存在Fork远程仓库 | origin | Fork远程仓库 |
| 多个远程仓库,其中一个是Fork | 非Fork远程仓库 | Fork远程仓库 |
**检测算法**:
```bashGet current user's GitHub username
获取当前用户的GitHub用户名
CURRENT_USER=$(gh api user -q '.login')
CURRENT_USER=$(gh api user -q '.login')
For each remote, check if it belongs to current user
遍历每个远程仓库,检查是否属于当前用户
for remote in $(git remote); do
REMOTE_URL=$(git remote get-url $remote)
Extract owner from URL (handles both HTTPS and SSH)
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
for remote in $(git remote); do
REMOTE_URL=$(git remote get-url $remote)
从URL中提取仓库所有者(支持HTTPS和SSH格式)
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
Default fallback
默认回退配置
UPSTREAM_REMOTE=${UPSTREAM_REMOTE:-origin}
FORK_REMOTE=${FORK_REMOTE:-origin}
undefinedUPSTREAM_REMOTE=${UPSTREAM_REMOTE:-origin}
FORK_REMOTE=${FORK_REMOTE:-origin}
undefinedStep 3: Sync Upstream Default Branch
步骤3:同步上游默认分支
bash
undefinedbash
undefinedFetch latest from upstream
从上游仓库拉取最新代码
git fetch $UPSTREAM_REMOTE $DEFAULT_BRANCH
git fetch $UPSTREAM_REMOTE $DEFAULT_BRANCH
Update local default branch
更新本地默认分支
git checkout $DEFAULT_BRANCH
git pull $UPSTREAM_REMOTE $DEFAULT_BRANCH
git checkout $DEFAULT_BRANCH
git pull $UPSTREAM_REMOTE $DEFAULT_BRANCH
Return to feature branch
切换回功能分支
git checkout $CURRENT_BRANCH
undefinedgit checkout $CURRENT_BRANCH
undefinedStep 4: Update Current Branch with Upstream
步骤4:用上游代码更新当前分支
bash
undefinedbash
undefinedRebase current branch onto latest default branch
将当前分支变基到最新的默认分支
git rebase $UPSTREAM_REMOTE/$DEFAULT_BRANCH
git rebase $UPSTREAM_REMOTE/$DEFAULT_BRANCH
If rebase fails, inform user
如果变基失败,告知用户
if [ $? -ne 0 ]; then
echo "Rebase failed. Please resolve conflicts manually."
git rebase --abort
exit 1
fi
undefinedif [ $? -ne 0 ]; then
echo "Rebase failed. Please resolve conflicts manually."
git rebase --abort
exit 1
fi
undefinedStep 5: Push Branch to Remote
步骤5:推送分支到远程仓库
Check if branch exists on remote and push:
bash
undefined检查分支是否已存在于远程仓库并执行推送:
bash
undefinedCheck if branch exists on the push remote
检查推送远程仓库中是否存在该分支
REMOTE_BRANCH_EXISTS=$(git ls-remote --heads $FORK_REMOTE $CURRENT_BRANCH | wc -l)
if [ "$REMOTE_BRANCH_EXISTS" -eq 0 ]; then
Branch doesn't exist, push with upstream tracking
git push -u $FORK_REMOTE $CURRENT_BRANCH
else
Branch exists, force push (after rebase) with lease for safety
git push --force-with-lease $FORK_REMOTE $CURRENT_BRANCH
fi
**Important**: Always use `--force-with-lease` instead of `--force` for safety.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
分支已存在,变基后使用--force-with-lease安全推送
git push --force-with-lease $FORK_REMOTE $CURRENT_BRANCH
fi
**重要提示**:为了安全起见,请始终使用`--force-with-lease`而非`--force`进行推送。Step 6: Gather PR Content Information
步骤6:收集PR内容信息
bash
undefinedbash
undefinedGet all commits between default branch and current branch
获取默认分支与当前分支之间的所有提交记录
git log $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD --pretty=format:"%h %s%n%b" --no-merges
git log $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD --pretty=format:"%h %s%n%b" --no-merges
Get the diff summary
获取代码差异统计
git diff --stat $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
git diff --stat $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
Get the full diff for analysis
获取完整的代码差异用于分析
git diff $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
git diff $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
Get list of changed files
获取已更改的文件列表
git diff --name-only $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
undefinedgit diff --name-only $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD
undefinedStep 7: Check for PR Template
步骤7:检查PR模板
bash
undefinedbash
undefinedCheck for PR template in common locations
检查常见位置是否存在PR模板
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
".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
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
".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
Also check for template directory
同时检查模板目录
if [ -z "$PR_TEMPLATE" ] && [ -d ".github/PULL_REQUEST_TEMPLATE" ]; then
Use default template if exists
if [ -f ".github/PULL_REQUEST_TEMPLATE/default.md" ]; then
PR_TEMPLATE=".github/PULL_REQUEST_TEMPLATE/default.md"
fi
fi
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
Read template content if found
如果找到模板则读取其内容
if [ -n "$PR_TEMPLATE" ]; then
cat "$PR_TEMPLATE"
fi
undefinedif [ -n "$PR_TEMPLATE" ]; then
cat "$PR_TEMPLATE"
fi
undefinedStep 8: Generate PR Title and Description
步骤8:生成PR标题和描述
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 |
|---|---|
| Summarize changes from commits and diff |
| List key changes from diff |
| Extract from commit bodies or infer from changes |
| List test files changed or suggest manual testing |
| Leave placeholder if UI changes detected |
| Leave checkboxes for user to complete |
| Extract issue references from commits |
If no template, generate structured description:
markdown
undefined标题生成规则:
- 如果只有单个提交:使用提交信息的主题行
- 如果有多个提交:总结整体变更内容
- 如果项目使用约定式提交格式,请遵循:
<type>(<scope>): <description> - 长度控制在72字符以内
描述生成规则:
如果存在PR模板,则填充模板中的对应部分:
| 常见模板部分 | 填充方式 |
|---|---|
| 从提交记录和代码差异中总结变更内容 |
| 列出代码差异中的关键变更 |
| 从提交说明中提取或根据变更内容推断 |
| 列出已更改的测试文件或建议手动测试方式 |
| 如果检测到UI变更则保留占位符 |
| 保留复选框供用户完成 |
| 从提交记录中提取关联的Issue引用 |
如果没有模板,则生成结构化描述:
markdown
undefinedSummary
摘要
[2-3 sentences summarizing what this PR does]
[2-3句话总结该PR的作用]
Changes
变更内容
- [Key change 1]
- [Key change 2]
- [Key change 3]
- [关键变更1]
- [关键变更2]
- [关键变更3]
Testing
测试说明
[How the changes were tested or should be tested]
[Any issue references found in commits]
undefined[变更内容的测试方式或建议测试方式]
[提交记录中找到的所有Issue引用]
undefinedStep 9: Create the Pull Request
步骤9:创建Pull Request
bash
undefinedbash
undefinedDetermine the base repository for the PR
确定PR的目标基准仓库
if [ "$IS_FORK" = "true" ]; then
For forks, create PR against parent repo
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
--repo "$BASE_REPO"
--base "$DEFAULT_BRANCH"
--head "$CURRENT_USER:$CURRENT_BRANCH"
--title "$PR_TITLE"
--body "$PR_BODY" else
For non-forks, create PR in same repo
gh pr create
--base "$DEFAULT_BRANCH"
--head "$CURRENT_BRANCH"
--title "$PR_TITLE"
--body "$PR_BODY" fi
--base "$DEFAULT_BRANCH"
--head "$CURRENT_BRANCH"
--title "$PR_TITLE"
--body "$PR_BODY" fi
**Use HEREDOC for body to preserve formatting**:
```bash
gh pr create --title "$PR_TITLE" --body "$(cat <<'EOF'if [ "$IS_FORK" = "true" ]; then
对于Fork仓库,向父仓库创建PR
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
--repo "$BASE_REPO"
--base "$DEFAULT_BRANCH"
--head "$CURRENT_USER:$CURRENT_BRANCH"
--title "$PR_TITLE"
--body "$PR_BODY" else
对于非Fork仓库,在当前仓库内创建PR
gh pr create
--base "$DEFAULT_BRANCH"
--head "$CURRENT_BRANCH"
--title "$PR_TITLE"
--body "$PR_BODY" fi
--base "$DEFAULT_BRANCH"
--head "$CURRENT_BRANCH"
--title "$PR_TITLE"
--body "$PR_BODY" fi
**使用HEREDOC保留格式传递PR内容**:
```bash
gh pr create --title "$PR_TITLE" --body "$(cat <<'EOF'Summary
摘要
[Generated summary here]
[生成的摘要内容]
Changes
变更内容
- Change 1
- Change 2
EOF
)"
undefined- 变更1
- 变更2
EOF
)"
undefinedStep 10: Report Results
步骤10:报告结果
After PR creation, provide:
bash
undefinedPR创建完成后,提供以下信息:
bash
undefinedGet PR URL and details
获取PR的URL和详细信息
gh pr view --json url,number,title,state
undefinedgh pr view --json url,number,title,state
undefinedOutput Format
输出格式
PR Created Successfully
PR创建成功
PR: #[NUMBER] - [TITLE]
URL: [PR_URL]
Base: [BASE_BRANCH] ← Head: [HEAD_BRANCH]
Remote: Pushed to
[FORK_REMOTE]PR: #[编号] - [标题]
URL: [PR链接]
基准分支: [基准分支] ← 头部分支: [头部分支]
远程仓库: 已推送到
[FORK_REMOTE]Summary
摘要
[Brief description of what the PR contains]
[PR内容的简要描述]
Files Changed
已更改文件
| File | Changes |
|---|---|
| +[additions] -[deletions] |
| 文件 | 变更统计 |
|---|---|
| +[新增行数] -[删除行数] |
Next Steps
后续步骤
- Review the PR description and edit if needed
- Add reviewers if required
- Wait for CI checks to pass
- Address any review comments
- 查看PR描述并根据需要编辑
- 如果需要则添加审核人员
- 等待CI检查通过
- 处理审核意见
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 |
| Fork detection failed | "Could not determine fork relationship. Please specify the target repo." |
| 场景 | 操作 |
|---|---|
| 基准分支之后无提交记录 | "没有可创建PR的变更内容,你的分支与[基准分支]保持同步。" |
| 变基冲突 | "变基因冲突失败,请手动解决冲突后重新运行。" |
| 推送被拒绝 | "推送失败,请检查你是否拥有远程仓库的写入权限。" |
| 该分支的PR已存在 | "该分支对应的PR已存在:[链接]。正在打开已有的PR。" |
| 无法访问远程仓库 | "无法访问远程仓库,请使用 |
| Fork关系检测失败 | "无法确定Fork关系,请指定目标仓库。" |
Advanced Options
高级选项
Draft PR
草稿PR
bash
gh pr create --draft --title "$PR_TITLE" --body "$PR_BODY"bash
gh pr create --draft --title "$PR_TITLE" --body "$PR_BODY"Add Reviewers
添加审核人员
bash
gh pr create --reviewer "user1,user2" --title "$PR_TITLE" --body "$PR_BODY"bash
gh pr create --reviewer "user1,user2" --title "$PR_TITLE" --body "$PR_BODY"Add Labels
添加标签
bash
gh pr create --label "enhancement,needs-review" --title "$PR_TITLE" --body "$PR_BODY"bash
gh pr create --label "enhancement,needs-review" --title "$PR_TITLE" --body "$PR_BODY"Link to Issue
关联Issue
If commits reference issues (e.g., "Fixes #123"), automatically add to PR body:
bash
undefined如果提交记录中引用了Issue(例如:"Fixes #123"),则自动添加到PR内容中:
bash
undefinedExtract issue references from commits
从提交记录中提取Issue引用
ISSUES=$(git log $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD --pretty=format:"%B" | grep -oE "(Fixes|Closes|Resolves) #[0-9]+" | sort -u)
undefinedISSUES=$(git log $UPSTREAM_REMOTE/$DEFAULT_BRANCH..HEAD --pretty=format:"%B" | grep -oE "(Fixes|Closes|Resolves) #[0-9]+" | sort -u)
undefinedImportant Notes
重要说明
- Safety First: Always use instead of
--force-with-leasewhen pushing after rebase--force - 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
- 安全第一:变基后推送时,请始终使用而非
--force-with-lease--force - Fork感知:自动检测并处理Fork工作流
- 遵循模板:始终检查并使用现有的PR模板
- 约定式提交:如果项目使用约定式提交格式,请遵循该格式
- Issue关联:保留提交记录中的Issue引用
- 提交前审核:在创建PR前向用户展示生成的标题/描述,待用户确认后再提交