Back to blog
Engineering25 min read

PR Description Prompts (and the Commit Messages That Feed Them)

33 PR description prompts organised by the job each section does: summary, why, risk, review focus, test evidence, scope and rollback. Plus the commit prompts that feed them.

NH
Nafiul Hasan
Founder, Prompt Architects

TL;DR: A model reading your diff can describe what changed with real accuracy. It cannot know why you changed it. So generate the structure and the what, write the why yourself, and never let a prompt infer test coverage. Twenty-eight copy-paste PR description prompts below, plus five commit prompts that feed them.

What can a model actually write in a PR description?

Half of it, and reliably. Give a model a diff and it will tell you which files changed, what the behaviour change is, which call sites moved, and which public shapes are now different. That half is mechanical, and models are good at mechanical.

The other half is not in the diff and never was. The ticket that triggered the work, the incident last Tuesday, the constraint from the platform team, the approach you tried first and abandoned, the thing you deliberately did not fix. None of that is recoverable from a patch. A model asked for it anyway will produce something plausible, because plausible is what it does when a fact is missing, for the same reason it confidently invents citations. The longer version of that mechanism is in why models make things up.

So a fully generated PR description is at its most fluent exactly where it is emptiest. It reads finished. The "Why" heading is populated. A reviewer skims it, believes it, and approves a change on the strength of a reason nobody gave.

GitHub says the quiet part in its own documentation for the Copilot summary feature: "GitHub Copilot does not take into account any existing content in the pull request description, so start with a blank description for best results", and then, in the next step, tells you to review the summary carefully and add any additional context (docs.github.com, accessed 28 August 2026). That is the entire workflow in two instructions. The model does the what. You add the why afterwards.

What does a PR description have to do?

It has seven jobs, and they are genuinely different tasks. Most template posts list them as headings and stop there, which is why so many PR descriptions have all the right headings and none of the right content. Here is which half of each job a model can do:

JobFrom the diff aloneWhat you must supply
Summarise what changedYes, accuratelyNothing
Explain whyNoThe ticket, incident, constraint, or decision
Flag risk and blast radiusPartly, from the file listWhich parts are load-bearing in production
Route the reviewerPartly, by file size and churnWhere you are least confident
State what was testedNoThe list of what you actually ran
Call out what is out of scopeNoYour own boundary decision
Migration and rollback notesPartly, from schema and config diffsOrdering, timing, and the undo path

Two of those seven are safely automatable. Three are half-automatable. Two are entirely yours. Any prompt that pretends otherwise is generating the shape of a description rather than a description.

How do commit messages feed the PR description?

Mechanically, in three places, which is why the commit half of this workflow is worth ten minutes even if you only care about PRs.

The first is the CLI. GitHub's gh pr create documents --fill as "Use commit info for title and body", --fill-first for the first commit's info, and --fill-verbose to "Use commits msg+body for description" (cli.github.com manual, accessed 28 August 2026). Your commit subjects become your PR body with no model involved at all.

The second is squash merging. GitHub's merge documentation states that when you squash and merge, it generates a default commit message you can edit, and that "The default message can include the pull request title, pull request description, or commit information, depending on repository settings and the number of commits in the pull request" (docs.github.com, accessed 28 August 2026). In a squash-merge repository, the PR description is not a disposable review artefact. It becomes the permanent commit body that someone will read from git log in three years.

The third is legibility. A branch of ten commits called "wip", "fix", "fix again" gives a model nothing to group by, so it falls back to the diff and produces a flat list of files.

Post 280 covers commit messages properly, including the Conventional Commits grammar and the parser-level traps around breaking-change footers, and there is no point restating it here: the commit message generator prompts live there. What follows is the subset that exists to make the PR description better.

Prompt 1: commit subjects a PR description can group

Here is my staged diff:

<paste `git diff --cached`>

Write a one-line commit subject in my repository's convention, which is:
<paste one real example subject from `git log --oneline -5`>

Rules:
- Describe the behaviour change, not the edit. "handle expired refresh tokens"
  beats "update auth.ts".
- If the diff does more than one thing, say so and stop. Do not invent a
  subject that covers both.
- Then list, under the heading INFERRED, anything in your subject that you
  read between the lines rather than off the diff.

Prompt 2: a commit body that survives a squash

Same diff. Write a commit body of two to four lines.

You may only state motivation I give you here: <two sentences, or write NONE>.

If I wrote NONE, the body must contain only what the diff shows, and must end
with the line "REASON NOT SUPPLIED". Do not guess at intent, urgency, or which
bug this fixes.

Prompt 3: split the branch before you open the PR

Here are my commits on this branch:

<paste `git log --format='%h %s' origin/main..HEAD`>

And the diffstat:

<paste `git diff --stat origin/main..HEAD`>

Group these into the smallest number of independently reviewable changes. For
each group: a name, the commits in it, and one sentence on whether it could
ship alone. Then tell me plainly whether this should be one PR or several, and
what the reviewer pays if it stays as one.

Prompt 4: turn a messy range into PR-ready bullets

Rewrite these commit subjects as bullets for a PR description. Group them by
what a reviewer cares about: behaviour changes first, then refactors, then
chores. Keep each bullet under 12 words. Drop pure fixup commits entirely
rather than listing them. If two commits undo each other, say so instead of
listing both.

Prompt 5: the squash-merge body

This branch will be squash-merged, so the PR description becomes the commit
body on the default branch permanently.

Given the commit range below and my reason (<two sentences>), write a commit
body that will still be useful to someone running `git log` in three years.
Include the issue reference. Exclude anything that only makes sense during
review, such as "addressed review comments" or "rebased on main".

The base prompt: a diff in, a PR description out

This is the one to save. Everything after it is a sharper tool for one section.

Prompt 6: the full PR description

You are writing a pull request description for reviewers on my team.

INPUTS
Diffstat:
<paste `git diff --stat origin/main..HEAD`>

Commit subjects:
<paste `git log --format='%s' origin/main..HEAD`>

Changed public interfaces (functions, routes, columns, env vars) if any:
<paste, or write NONE>

MY REASON (the only source for the Why section):
<two to four sentences. If you leave this blank, do not fill it in.>

TESTED (the only source for the test section):
<list what you actually ran. If you leave this blank, write NOT TESTED.>

OUTPUT — exactly these sections, in this order:

## Summary
Three to six bullets. Behaviour changes only. No file tours.

## Why
Only my reason above, tightened. If I supplied nothing, write
"REASON NOT SUPPLIED" and nothing else.

## Risk and blast radius
What breaks if this is wrong, and who notices first. Mark each item
OBSERVED (visible in the diff) or ASSUMED (your inference).

## Review focus
Three items. Each names a real file or function from the diffstat and says
what to check about it. Order them most-uncertain first.

## Tested
Only what I listed under TESTED. Everything else in the change surface gets
one line under "NOT TESTED".

## Out of scope
Only what I named. If I named nothing, omit this section entirely.

RULES
- Never write a sentence whose evidence is not in the inputs.
- No adjectives about quality. Not "clean", not "robust", not "minor".
- End with a section called ASSUMPTIONS listing every inference you made.

The ASSUMPTIONS block at the end is the part that pays for itself. It takes fifteen seconds to read and requires no judgement: you either said that or you did not.

How do you get the why in when the model cannot know it?

By making the model ask you first. The single highest-leverage change to this whole workflow is inverting the order: instead of generating a description and hoping you notice the invented reasoning, get interrogated for ninety seconds and then generate. It is the same mechanism as getting the model to ask questions first, applied to the one input that is never in the repository.

Prompt 7: interview me before you write anything

Do not write the PR description yet.

Read the diffstat and commit subjects below, then ask me between three and five
questions whose answers you cannot get from the diff. Prioritise: what triggered
this work, what you rejected, what you deliberately left broken, and what you
are least sure about. Ask nothing you could answer yourself.

Wait for my answers before writing anything.

Prompt 8: the reason, in three registers

Here is my reason, written badly and at speed:
<paste your raw notes, including the swearing>

Rewrite it three ways, and label them:
(a) one sentence for the PR title area
(b) two to three sentences for the Why section
(c) one line for the commit body

Do not add causes, urgency, or business impact I did not write. If my notes
are too vague to support (b), say so and ask one question.

Prompt 9: the rejected alternative

I considered <approach A> and chose <approach B>. Write a two-sentence note for
the PR description explaining the tradeoff, in a form a reviewer can disagree
with. Name the cost of the choice, not only its benefit. Do not editorialise
about which is better.

Prompt 10: link the reason to its evidence

Rewrite my Why section so every claim carries its source in brackets:
[ticket], [incident], [review comment], [my judgement]. If a claim has no
source, delete it rather than labelling it.

That last one produces a section that looks slightly bureaucratic and is worth it. GitHub's Copilot code review documentation notes that it is more likely to pull in extra context when a repository or pull request gives clear signals, including "pull request descriptions that include identifiers referencing configured MCP servers such as issue keys or incident IDs" (docs.github.com, accessed 28 August 2026). Writing the identifier down helps a human reviewer and, on that platform, the automated one too.

How do you summarise what changed without restating the diff?

By forcing the summary up an altitude. A model given a diff will happily write "updates parseToken to handle nested claims", which is the diff in English and adds nothing a reviewer could not get from the Files tab in eight seconds.

Prompt 11: behaviour, not edits

Rewrite each of these bullets so it describes a change in observable behaviour
rather than a change to code. Before: "refactors the retry helper". After:
"retries now stop after 30s instead of retrying forever".

If a bullet has no observable behaviour change, move it to a section called
"Internal only" instead of rewriting it.

Prompt 12: three altitudes

From the same inputs, produce the summary at three lengths:
(a) one sentence, for the PR title
(b) one paragraph, for someone deciding whether to review it
(c) bullets, for the reviewer who said yes

Each must be independently readable. Do not make (b) a preamble to (c).

Prompt 13: strip the marketing

Here is a draft PR description:
<paste>

Delete every sentence that praises the change, restates a heading, or says
something true of any pull request ("improves maintainability", "follows best
practices", "no breaking changes expected"). Return what survives. If a section
is empty after deletion, say so rather than refilling it.

Prompt 14: the diff-to-summary sanity check

Here is my PR description and the diffstat it claims to describe.

List every claim in the description that the diffstat does not support, and
every changed file that the description never mentions. Do not fix anything.
Output two lists only.

How do you make the description flag risk and blast radius?

By asking for two separate things. Risk is what could go wrong; blast radius is how far it spreads if it does. A model can infer the second from the file list surprisingly well and cannot infer the first without knowing your production shape.

Prompt 15: blast radius from the file list

Given these changed files, list what depends on them, using only what you can
see in the repository: importers, route handlers, tests, config. For each, say
whether the change is source-compatible.

Mark anything you could not check as UNVERIFIED. Do not estimate percentages
of traffic or numbers of users.

Prompt 16: the risk register

Write four to six risk lines for this PR. Format each as:
"<what breaks> — noticed by <who or what> — within <how long>".

Only include risks traceable to a specific change in the diff. If the honest
answer for detection is "nobody would notice", write that. Do not include
generic risks such as "unforeseen edge cases".

Prompt 17: the reviewer's cost estimate

Estimate how long a careful review of this diff takes, and say which files
account for most of that time. Then tell me the single split that would most
reduce review cost, or say that no useful split exists.

Prompt 18: config and secrets sweep

Scan this diff for anything that changes runtime configuration: environment
variables added, removed or renamed; default values changed; feature flags;
timeouts; retry counts; cache TTLs.

List each with its old and new value. Flag any that need a deployment step
before or after the merge. If a variable is added but has no default, say so
loudly.

Where should a reviewer start, and what should they look at hardest?

Those are two questions, and the second one is where honesty gets uncomfortable. The most useful line in any PR description is the one that says which part you are least sure about, and no model can write it for you.

Prompt 19: routing

Write a "Start here" line naming one file and one function, chosen so that
understanding it makes the rest of the diff obvious. Justify the choice in one
sentence. Do not pick the largest file by default.

Prompt 20: hardest-look list

Produce three "look hardest at" items. Each must name a file and a specific
question, not a category. Good: "does `applyDiscount` still round before tax in
`billing/total.ts`?" Bad: "check the billing logic".

Rank by how expensive the mistake would be, not by how likely it is.

Prompt 21: the confidence line

I am least confident about: <write it yourself, one sentence>.

Turn that into a line for the PR description that tells a reviewer exactly what
to verify and what evidence would settle it. Do not soften it. Do not add
reassurance.

Prompt 22: reviewer-side, for the other end

You are the reviewer. Here is a PR description and diffstat.

Tell me what this description does not tell me that I need in order to approve
it. Then list the three questions I should ask the author before reading a
single line of code.

Prompt 22 is worth running against your own description before you open the PR, for the same reason that prompting for a genuinely useful code review works better when you ask what is missing rather than what is wrong.

How do you state what was tested without overstating it?

This is the part of a generated PR description that does real damage, and it is worth being blunt about why.

A model that sees auth/token.test.ts in the diffstat will write "unit tests added and passing". It does not know they pass. It does not know what they assert. It does not know you commented one out at 1am. The sentence is not a summary of evidence, it is a prediction of what a diff of that shape usually means, and reviewers ration attention by claimed coverage. An overstated test line does not just fail to help. It actively redirects scrutiny away from the code that needed it.

Prompt 23: evidence only

TESTED (my input, verbatim):
<paste what you actually ran, including "nothing">

Write the Tested section. Rules:
- Include only what I listed. Do not infer from filenames, test files in the
  diff, or CI config.
- For every behaviour change in the diff that my list does not cover, add one
  line under "NOT TESTED" naming it.
- Never write "should work", "expected to pass", or "covered by existing tests"
  unless I wrote it.

Prompt 24: the coverage gap, stated for the reviewer

Compare my TESTED list against the behaviour changes in this diff. Output one
section called "What a reviewer should not assume is covered", listing each gap
in plain language. No remediation advice. Just the gaps.

Prompt 25: manual QA steps someone else can run

Write reproduction steps for the change, for a reviewer who has never seen this
feature. Numbered, starting from a clean checkout, with the exact commands and
the expected observable result at each step.

Mark any step that needs data, credentials or access I have not mentioned as
PREREQUISITE UNKNOWN rather than inventing setup.

Prompt 26: the rollback rehearsal

Describe how to undo this change in production, in order. Include: revert
mechanics, whether the revert is safe if the migration has already run, what
data would be lost, and what would need to be done manually.

If the change is not cleanly revertible, say that in the first line.

What belongs in the out-of-scope block, and what needs a migration note?

Out of scope is a boundary you drew, so the model cannot draw it. What it can do is turn your boundary into something a reviewer will not re-litigate in comments.

Prompt 27: scope fence

I deliberately did not do these things in this PR:
<list them, however roughly>

For each, write one line for an "Out of scope" section giving the boundary and
the reason. Then write the follow-up issue titles I should file, one per item,
in the imperative. Do not add items I did not list.

Prompt 28: the migration note

This diff contains a schema or data migration:
<paste the migration file>

Write a migration note covering: what runs, in what order relative to the
deploy, how long it takes on a table of <size>, whether it takes a lock,
whether old application code keeps working during it, and whether it is
reversible.

Mark anything not determinable from the file itself as NEEDS CONFIRMATION.
Do not estimate duration if I did not give you a row count.

Prompt 29: backward compatibility statement

List every change in this diff that an existing client, stored row, saved URL
or cached value could depend on. For each, state whether the old shape still
works after this merge.

Where the answer is no, write the compatibility note as a sentence a support
engineer could paste to a customer.

Prompt 30: closing keywords, correctly formed

These issues are addressed by this PR: <list, e.g. 412, 415, and org/repo#88>.

Write the linking lines using GitHub's closing-keyword syntax, repeating the
full keyword and reference for every issue rather than comma-chaining bare
numbers. Put them on their own lines at the end of the description.

That last rule is not stylistic. GitHub's documentation gives the syntax for multiple issues as "Use full syntax for each issue", with the example Resolves #10, resolves #123, resolves octo-org/octo-repo#100 (docs.github.com, accessed 28 August 2026). A model left to itself writes Fixes #10, #12, which links exactly one issue and silently leaves the other open.

Which platform features should your prompt know about?

Enough of them that the description it writes actually functions. All of the following were verified on the platform's own documentation on 28 August 2026.

FeatureWhat the docs sayWhy the prompt should care
GitHub PR templatepull_request_template.md in the repo root, in docs/, or in .github/; .github/PULL_REQUEST_TEMPLATE/ for multiple, chosen with the template query parameterThe template is the output contract; paste it into the prompt
Template availability"Templates are available to collaborators when they are merged into the repository's default branch."A template on your branch does nothing yet
Closing keywordsNine: close, closes, closed, fix, fixes, fixed, resolve, resolves, resolved; may be uppercase or followed by a colonGenerated descriptions invent variants like "addresses"
Keyword scope"The special keywords in a pull request description are interpreted only when the pull request targets the repository's default branch."On a release branch, your auto-close silently does nothing
Manual linksUp to ten issues can be manually linked to a pull requestThe description is not the only linking mechanism
Draft PRs"Marking a pull request as ready for review will request reviews from any code owners."A draft description has a different job: status, not summary
Squash mergeDefault message "can include the pull request title, pull request description, or commit information"Your description may become the permanent commit body
GitLab MR templates.gitlab/merge_request_templates/, .md extension, "Present on the default branch." Projects inherit from group and instanceDifferent path, same contract-paste trick
Copilot PR summary"GitHub Copilot does not take into account any existing content in the pull request description"Generate first, then add your reasoning, not the reverse
Copilot code review"Copilot is not guaranteed to spot all problems or issues in a pull request." "Always validate Copilot's feedback carefully." Dependency management files, log files and SVG files are excluded from its reviewAn automated review is not test evidence, and a lockfile-heavy PR gets less of it than you think

The draft-PR row deserves its own prompt, because a draft description that reads like a finished one wastes everyone's time.

Prompt 31: the draft PR status note

This is a draft PR. Write a description whose job is status, not summary.

Sections: what works now, what is stubbed or fake, what I am blocked on, and
what specific feedback I want before I keep going. One line each. Do not write
a Tested section. Do not include closing keywords.

How do you turn your team's PR template into a prompt?

Paste it in as the output contract. This is the whole trick, and it beats every generic template in this post, because your template encodes arguments your team already had.

Prompt 32: template as contract

Here is my repository's pull request template, verbatim:
<paste .github/pull_request_template.md>

Fill it in from the inputs below. Rules:
- Keep every heading, comment and checkbox exactly as written, including
  HTML comments.
- Do not add sections. Do not remove sections.
- Any section you cannot fill from the inputs gets "REASON NOT SUPPLIED" or
  "NOT TESTED" as appropriate, never a guess.
- Leave checkboxes unchecked. You cannot verify a checkbox.

INPUTS: <diffstat, commit subjects, my reason, my tested list>

The unchecked-boxes rule matters more than it looks. A template checkbox reading "I have added tests" is an assertion by a person. A model that ticks it has forged a signature, and the reviewer has no way to tell which boxes were ticked by whom.

Prompt 33: extract the contract you already follow

Here are five recent merged PR descriptions from my repository:
<paste them>

Infer the conventions: section order, heading style, level of detail, what is
always present, what is never present, and how issue links are written.

Output the result as a reusable instruction block I can paste above a diff.
Flag anything inconsistent across the five rather than picking a favourite.

Prompt 33 is the one worth running once per repository. It converts an unwritten convention into a prompt template you can reuse, which is the point where this stops being a party trick and starts being a workflow.

This is also where we come in, so let me be exact about what we do and do not do. Prompt Architects has no GitHub or GitLab integration, no API, and nothing that opens a pull request for you. What it is, is the layer that keeps prompts like the thirty-three above out of a scratch file: a saved library with variables and context, so <paste your template> and <your repo's convention> are fields rather than things you re-hunt every Friday. Our MCP server is the part that matters for this particular job, because it puts improve, refine, shorten and enhance inside Claude Desktop, Claude Code, Cursor and Codex, which is where you already have the diff open. Setup is on the MCP integration page, and the mechanics of running an MCP server inside a coding agent are covered in using MCP inside Claude Code. The free plan includes 5 prompt enhancements per day, forever, per our FAQ page.

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 5.0★ on the Chrome Web Store.

Create An Account

Where these prompts reliably go wrong

Four failure modes, all predictable, which is what makes them cheap to catch.

The invented reason. Covered above, and it is the one that outlives you, because the PR description gets squashed into the commit body and read years later by someone with no way to check it.

The overstated test line. Also covered, and the one that changes reviewer behaviour rather than merely misinforming them.

The confident dependency claim. A model listing what depends on a changed function is reading the repository, not the runtime. Dynamic imports, reflection, string-keyed dispatch and anything called from another service are invisible to it. UNVERIFIED is a required output, not a hedge.

The tidy summary of a messy branch. If the branch does three unrelated things, a good prompt produces a description that makes it look like one coherent change. That is worse than no description, because it hides the mess from the reviewer instead of surfacing it. Prompt 3 exists to catch this before you get there.

A checklist before you click Create pull request

Seven checks, about a minute.

  1. Read the ASSUMPTIONS block first, before the description. Delete anything you did not say.
  2. Check the Why section is yours. If it says REASON NOT SUPPLIED, either write two sentences or leave it. Do not let the model fill it.
  3. Check the Tested section against what you ran, not against what is in the diff.
  4. Check every dependency claim for an UNVERIFIED marker that should be there and is not.
  5. Check the closing keywords are repeated in full per issue, and that you are targeting the default branch, or accept that they will not fire.
  6. Check no checkbox was ticked by the model.
  7. Check whether this repository squashes. If it does, read the description once more as a commit message, because that is what it is about to become.

The failure this list guards against is not the bad description. It is the good one that says something you never said, and which nobody will ever check again.

Frequently asked questions

Free Chrome Extension

Stop rewriting prompts. Start shipping.

Works with ChatGPT, Claude, Gemini, Grok, Midjourney, Ideogram, Veo3 & Kling. 5.0★ on the Chrome Web Store.

Create An Account