devpilot-pr-creator
Pull Request / Merge Request Skill
Core principle: Read the actual diff before writing anything. Every sentence in the description must come from code you read, not from branch names or assumptions.
Operating mode: automatic by default. Do not stop to confirm routine choices (branch name, commit message, draft body) — derive them from the diff and execute. Only stop for the destructive / ambiguous cases listed under Hard Stops. Showing a draft "for approval" before creating is not a hard stop; the user can gh pr edit after the fact.
Quick Reference
| Action | GitHub | GitLab |
|---|---|---|
| Create | gh pr create --title "..." --body "..." |
glab mr create --title "..." --description "..." |
| Update | gh pr edit <number> --title "..." --body "..." |
glab mr update <number> --title "..." --description "..." |
| Mark ready | gh pr ready <number> |
glab mr update <number> --draft=false |
| Base branch | --base <branch> |
--target-branch <branch> |
| Draft | --draft |
--draft |
| Push | git push -u origin HEAD |
git push -u origin HEAD |
Worktree / autonomous invocation
Detect both up front — they change preflight rules.
git rev-parse --git-dir # contains "/worktrees/" → you are in a linked worktree
git worktree list # confirms which worktree is which
You are in autonomous mode when this skill was invoked by a parent skill (e.g. devpilot-resolve-issues, devpilot-auto-feature) rather than directly by a human. In autonomous mode:
- The "stop and ask the user" gates below become "return control to the parent with the question" — never deadlock waiting for human input that isn't coming.
- Replace "show the draft to the user before creating" with "include the draft in your final response" so the parent skill can surface it.
- Do not
cdout of the worktree; the parent owns cwd.
Base branch. Always diff and log against origin/<default-branch> (typically origin/main), not local main. In a worktree the local main ref may be stale or absent. Run git fetch origin <default-branch> before reading the diff so the comparison is honest.
Preflight Checks
Before anything else, run these in parallel:
git remote get-url origin # detect platform (github.com → gh, gitlab.com → glab)
git rev-parse --abbrev-ref HEAD # current branch
git rev-parse --git-dir # worktree detection (see above)
git fetch origin <default-branch> --quiet # refresh base ref
git status # working tree state
git log origin/<default-branch>..HEAD --oneline # commits ahead of base
git diff --name-only origin/<default-branch>...HEAD # files in the PR
git ls-remote --heads origin <branch> # branch already on origin?
gh pr list --head <branch> # existing PR? (or glab mr list --source-branch)
Auto-recover: on main/master
If HEAD is on main/master, do not stop — recover automatically:
- Confirm none of the local commits ahead of base have been pushed to
origin/main. Ifgit log origin/main..HEADis empty AND the working tree is clean, there is nothing to PR — exit. If commits ahead of base have already been pushed to origin/main, stop: the PR window has passed (see Hard Stops). - Pick a feature branch name (see Branch naming).
git checkout -b <name>— this carries any uncommitted changes onto the new branch and leavesmainuntouched.- If there are uncommitted changes that belong in the PR,
git addthe relevant files (those whose paths overlap the intended PR scope) and commit with a conventional-commit message derived from the diff. Leave unrelated dirty files alone. - Continue with the normal flow.
Never run git reset, git push --force, git push --force-with-lease, or any history rewrite on main/master — not as a recovery, not as an "option," not ever.
Auto-recover: dirty working tree overlapping the PR diff
If modified/staged files overlap the PR diff, do not stop — stage and commit them as part of the PR with a conventional-commit message derived from the changes. Files outside the PR diff stay untouched.
Hard Stops
These are the only cases where you must stop. In autonomous mode, return the question to the parent instead of blocking:
- Work already pushed to
origin/main/origin/master. The PR window for those commits has passed. Do not try to "rescue" it with history rewriting. Tell the user. - No commits ahead of base AND no uncommitted changes. Nothing to PR.
- Open PR already exists for this branch. Switch to update flow (see below) — this isn't really a stop, just a branch in logic.
- Remote branch diverged.
git log HEAD..origin/<branch>is non-empty after fetching. Reconcile by inspecting; never force-push.
Do NOT block on: untracked files, or modified files outside the PR diff. These are common in worktrees (test artifacts, scratch logs, leftovers from a parent agent) and are already excluded from origin/<base>...HEAD. Note them in your report and proceed.
Branch naming
Derive deterministically — do not ask:
- If there are commits ahead of base, parse the latest commit subject. Take its conventional prefix (
feat,fix,chore,docs,refactor) and slugify the rest:<type>/<kebab-slug>(max ~50 chars). - Otherwise (only uncommitted changes), pick the prefix from the change shape —
fix:for bug language in modified code,docs:for.md-only,chore:for config/tooling, elsefeat:. Slug from the most-changed top-level directory or filename stem. - If a branch by that name already exists locally, append
-2,-3, etc.
Branch already on origin, but no open PR (common after a draft-escalation push from devpilot-resolve-issues):
- Only enter this branch if
git ls-remote --heads origin <branch>returned a SHA. If it was empty, skip —git push -u origin HEADwill create the remote ref normally. git fetch origin <branch>— see if remote has commits you don't.- If
git log HEAD..origin/<branch>is non-empty, stop — the remote diverged. Reconcile by inspecting; never force-push. - Otherwise
git push -u origin HEADwill fast-forward (or be a no-op). Then create the PR normally.
Read the Diff (Required)
git diff origin/<default-branch>...HEAD # full diff (always vs origin, not local)
git log origin/<default-branch>..HEAD --oneline
You MUST read and understand the actual changes before writing the description.
From the diff, determine:
- What files were added, modified, or deleted
- What the changes do functionally (bug fix? feature? refactor?)
- Whether there are test changes
- Whether there are breaking changes
Red flags — you're writing a bad description if:
- You're inferring what changed from the branch name instead of the diff
- You're using generic phrases like "implements skill definition and supporting logic"
- Your test plan mentions things not visible in the diff
- Your description would be the same for a completely different set of changes
Find the Template
Check for existing project templates first:
GitHub: .github/pull_request_template.md, .github/PULL_REQUEST_TEMPLATE.md, docs/pull_request_template.md, PULL_REQUEST_TEMPLATE.md, or files in .github/PULL_REQUEST_TEMPLATE/
GitLab: .gitlab/merge_request_templates/Default.md or files in .gitlab/merge_request_templates/
If a project template exists, use it. Fill it in based on the diff. Remove irrelevant sections entirely.
If no project template exists, read ONE template based on what you found in the diff:
| Changes touch frontend? | Bug fix or feature? | Read this file |
|---|---|---|
| Yes | Feature | templates/frontend-feature.md |
| Yes | Bug fix | templates/frontend-bugfix.md |
| No | Feature | templates/backend-feature.md |
| No | Bug fix | templates/backend-bugfix.md |
| Both | Either | Read both relevant templates, combine sections |
| Docs/config only | — | Use just Description + Review Guide, no template needed |
Only read the template you need. Do not read all four.
Write the Description
Title: Under 72 characters. Use conventional commit prefix (feat:, fix:, refactor:, docs:, chore:). Be specific — "fix: auth redirect loop in OAuth callback" not "fix: bug".
Review Guide (required): Every PR must include a Review Guide section:
- Which file to start reviewing first
- Suggested review order for large diffs
- Any tricky logic or non-obvious decisions to watch for
Body guidelines:
- Lead with what changed and why, based on the actual diff
- Reference specific files, functions, or behaviors you saw in the code
- Run the project's lint/test commands and report results in the checklist
- Leave "For Reviewers (human)" items unchecked — those are for humans
- For bug fixes, describe the bug, root cause, and fix separately
Do not stop to "show the draft for approval." Write the strongest title and body you can from the diff and create the PR directly. Report the URL afterward; the user can gh pr edit <number> if they want to tweak. In autonomous mode (invoked by a parent skill), include the final body inline in your response so the parent can surface it.
Create and Report
Push the branch if needed, create the PR/MR, and share the URL.
git push -u origin HEAD # if not already pushed
gh pr create --title "..." --body "..." # GitHub
glab mr create --title "..." --description "..." # GitLab
Update an Existing PR/MR
When preflight finds an open PR for the current branch, or the user explicitly asks to update:
1. Read the current PR state:
gh pr view <number> # GitHub — see current title, body, status
glab mr view <number> # GitLab
2. Read the full diff (same as creating — the description must reflect ALL commits, not just new ones).
3. Decide: preserve or rewrite.
- New commits added to an existing PR → rewrite the full description to cover all commits. Don't just append — re-read the complete diff and write a cohesive description.
- Reviewer feedback on description → address the specific feedback while keeping the rest.
- Draft → Ready → update description if it was a WIP placeholder, then mark ready.
4. Execute the update directly (do not stop for approval):
gh pr edit <number> --title "..." --body "..." # GitHub
glab mr update <number> --title "..." --description "..." # GitLab
5. Mark ready (if transitioning from draft):
gh pr ready <number> # GitHub
glab mr update <number> --draft=false # GitLab
Common Mistakes
| Mistake | Fix |
|---|---|
| Description based on branch name, not diff | Read git diff first. Always. |
| Generic test plan ("verify no regressions") | Reference specific test files or manual steps from the diff |
| Auto-checking all checklist items | Run lint/test commands for verifiable items; leave human items unchecked |
| No Review Guide section | Always tell reviewers where to start and what to watch for |
| Generic bug fix description ("fix bug") | Describe the bug symptom, root cause, and fix separately |
| Leaving irrelevant sections as "N/A" | Remove the section entirely |
| Force-pushing main to create a retroactive branch | Never offer this as an option. If work is on main and pushed, the PR opportunity has passed |
| Creating duplicate PR for branch with existing PR | Check gh pr list --head <branch> first — update instead |
| Blocking on untracked/unstaged files unrelated to the PR | Only block when the dirty files appear in origin/<base>...HEAD. Untracked debris in a worktree is common and already excluded |
Diffing against local main in a worktree |
Local main may be stale or absent in a worktree — always use origin/<default-branch> |
| Force-pushing because the branch already exists on origin | Fetch first; if remote diverged, reconcile, never force. Fast-forward push is fine |
| Appending to PR description instead of rewriting | Re-read the full diff and write a cohesive description covering all commits |
| Stopping to ask "should I create a feature branch?" when on main | Don't. Auto-create per Auto-recover: on main. The only main-related stop is when the work was already pushed to origin/main |
| Stopping to "show the draft for approval" before creating | Don't. Create directly; user edits after via gh pr edit |
| Asking the user to pick a branch name | Derive it per Branch naming. Don't prompt |
Red Flags — you are over-confirming
If you catch yourself about to write any of these, stop and just execute:
- "Want me to create a feature branch?"
- "Here's the draft — should I proceed?"
- "What should I name the branch?"
- "Should I commit these changes first?"
The only legitimate stops are listed under Hard Stops. Everything else is automatic.
Tips
- For stacked PRs, mention the dependency chain.
- If the diff is large, highlight the most important files for reviewers.
- Respect the user's language — if they write in Chinese, write the PR in Chinese (unless the project convention is English).
More from siyuqian/devpilot
devpilot-scanning-repos
Use when the user asks to scan, audit, or sweep an entire GitHub repository for issues and file them as tickets — "scan this repo", "audit the codebase", "find bugs/security holes/missing tests", "check the docs are still accurate", "/repo-scan", "open issues for all the problems you find". Scans security, edge cases, testing coverage, and doc/code drift (CLAUDE.md, AGENTS.md, README.md and the docs they link to) without assuming business logic. Do NOT use for reviewing a single PR (use devpilot-pr-review) or language-specific style review (use devpilot-google-go-style).
9devpilot-resolve-issues
Use when the user wants to resolve, fix, work through, or burn down open GitHub issues in a repository — "fix all the issues", "resolve these tickets", "work through the repo-scan issues", "clear the backlog", "fix issue #42", "/resolve-issues", "解决所有issue", "修复这些issue", "处理issue backlog". Runs as a loop over matching issues until none remain; each REAL issue is fixed in its own `git worktree` so the main checkout stays untouched. Do NOT use for creating issues (use devpilot-scanning-repos) or for reviewing a PR the user already has open (use devpilot-pr-review).
9devpilot-content-creator
SEO-optimized blog and content writing skill. Use this skill whenever the user wants to write a blog post, create content for their website, improve SEO rankings, do keyword research, or plan content strategy. Triggers on any mention of blog writing, SEO content, keyword research, content marketing, "写博客", "写文章", "内容创作", "SEO优化", or when the user wants to create any form of long-form content for a website or product. Even if the user just says "write something about X for our site", use this skill.
3devpilot-google-go-style
>
2devpilot-prompt-review
Review and improve prompts for Claude (system prompts, CLAUDE.md files, SKILL.md files, API prompts, or any LLM instruction text). Use this skill whenever the user wants to review a prompt, improve prompt quality, check prompt best practices, audit instructions for Claude, optimize a system prompt, or asks "is this prompt good?". Also trigger when the user shares a prompt and asks for feedback, or when they mention prompt engineering, prompt optimization, or prompt hygiene. Even if they just paste a prompt and say "thoughts?" — use this skill.
2devpilot-issue-triage
Use when the user wants to triage, classify, sort, or sweep open GitHub issues to decide what's worth working on — "triage these issues", "整理 backlog", "哪些可以马上修", "/triage", "sort the open issues". Sits between devpilot-scanning-repos (which files issues) and devpilot-resolve-issues (which fixes them). Read-only against GitHub — drafts comments and labels into a local report but never posts. Do NOT use for filing new issues, executing fixes, or reviewing a single PR.
2