Creating a Pull Request from a Claude Code Session with gh
Once Claude Code has made a set of changes in a working session, it can commit them and open a pull request against GitHub without leaving that session, using the gh CLI.
Summary
Opening a PR from a session means Claude Code runs the same git and gh commands a developer would type by hand.
There is no separate "Claude Code PR feature" - the gh CLI is GitHub's own official command-line tool, and Claude Code simply invokes it.
That means anything you could do with gh pr create yourself, Claude Code can do as part of finishing a task you asked for.
It also means the PR that results looks completely normal to your team - same title format, same body, same checks running against it.
The only prerequisite is that gh is installed and authenticated in the environment the session is running in.
Recipe
Quick-reference recipe card - copy-paste ready.
git add -A
git commit -m "Add rate limiting to the search endpoint"
git push -u origin HEAD
gh pr create --title "Add rate limiting to the search endpoint" \
--body "Adds a sliding-window rate limiter to the search endpoint. Fixes #482."When to reach for this:
- You've asked Claude Code to implement a feature or fix, and the change is ready to review.
- You want the PR title and body written in the same session that made the change, so the description matches the actual diff.
- You're working on a feature branch and want to skip switching to a browser to open the PR.
- You want a repeatable pattern you can also drop into a script or CI step later.
Working Example
#!/usr/bin/env bash
set -euo pipefail
# 1. Confirm there is something to commit.
git status --short
# 2. Stage and commit the change.
git add -A
git commit -m "Add rate limiting to the search endpoint
Adds a token-bucket limiter in middleware/rate-limit.py, applied to
the /api/search route. Limit is 60 requests/minute per API key."
# 3. Push the current branch, creating it on the remote if needed.
git push -u origin HEAD
# 4. Open the PR against the repository's default base branch.
gh pr create \
--title "Add rate limiting to the search endpoint" \
--body "$(cat <<'EOF'
## Summary
- Adds a token-bucket rate limiter to /api/search
- Limit: 60 requests/minute per API key
- Returns HTTP 429 with a Retry-After header when exceeded
## Test plan
- [x] Unit tests for the limiter's window boundaries
- [x] Manual test: exceeded the limit locally and confirmed 429 response
Fixes #482
EOF
)"
# 5. Print the new PR's URL for confirmation.
gh pr view --web=false --json url --jq .urlWhat this demonstrates:
- Using a heredoc (
$(cat <<'EOF' ... EOF)) to pass a multi-paragraph PR body without escaping issues. - Pushing with
-uso the branch is tracked on the remote beforegh pr createruns. - Structuring the PR body with a Summary and Test plan, which matches what most review-oriented teams expect.
- Confirming the result with
gh pr view --json urlinstead of assuming the command succeeded. - Referencing an issue number (
Fixes #482) so GitHub auto-links and closes the issue on merge.
Deep Dive
How It Works
gh pr createreads the current branch's tracking information to determine what to push against, and the repository's default branch (usuallymain) as the PR's base unless--baseis passed explicitly.- The command requires the branch to already exist on the remote -
git push -u origin HEADhandles that in one step by both pushing and setting up tracking. --titleand--bodyare optional; omitting them dropsghinto an interactive prompt, which is why session-driven usage almost always supplies both explicitly.- Once created,
gh pr createprints the new PR's URL to stdout, which is useful for a session to report back to you. - Under the hood,
ghauthenticates using the token stored bygh auth login, the same credential used for every otherghsubcommand.
Flags at a Glance
| Flag | Purpose |
|---|---|
--title | Sets the PR title directly, skipping the interactive prompt. |
--body | Sets the PR description; supports multi-line text via a heredoc or --body-file. |
--base | Overrides the default base branch (e.g. --base develop). |
--draft | Opens the PR as a draft, useful for work still in progress. |
--reviewer | Requests a specific reviewer or team by username/handle. |
--fill | Auto-fills title and body from the branch's commit history instead of specifying them. |
Bash Notes
# --fill saves typing when the branch has one clean commit whose message
# already reads like a good PR title and body.
git add -A
git commit -m "Add rate limiting to the search endpoint"
git push -u origin HEAD
gh pr create --fillGotchas
- Forgetting to push before
gh pr create.gh pr createneeds the branch to exist on the remote first; if you skipgit push -u origin HEAD, the command fails asking you to push. Fix: always push with-uimmediately before creating the PR, or let--fill's prompt push it for you. - Committing directly on the default branch. Opening a PR from
mainagainstmaindoesn't make sense -gh pr createwill error or behave unexpectedly. Fix: create and check out a feature branch (git checkout -b <branch-name>) before making changes. - An expired or missing
ghauth token. Commands silently fail with an authentication error ifgh auth loginwas never run or the token expired. Fix: rungh auth statusfirst; re-authenticate withgh auth loginif it reports not logged in. - A PR body with unescaped special characters. Passing
--bodyas a plain quoted string can break on embedded quotes or backticks. Fix: use a heredoc (as in the Working Example) or write the body to a file and pass--body-file. - Assuming
gh pr createopens against the branch you meant. If you're not on the branch you think you are, the PR ends up with the wrong diff. Fix: rungit statusorgit branch --show-currentimmediately before creating the PR to confirm. - Opening a PR with no linked issue when your team requires one. Some review processes expect every PR to reference a tracking issue. Fix: include
Fixes #<number>orRefs #<number>in the body, and confirm the issue number before running the command.
Alternatives
| Alternative | Use When | Don't Use When |
|---|---|---|
| Open the PR manually in the GitHub web UI | You want to review the diff visually before writing the description | You're already in a Claude Code session and want to avoid switching context |
gh pr create --fill | The branch has one clean, well-written commit message | The change spans several commits and needs a hand-written summary |
| A GitHub Actions workflow that opens PRs on a schedule (e.g. dependency bumps) | The PR is fully automated and doesn't need session-driven judgment | The PR body needs to describe reasoning specific to this session's work |
git push plus a separate CI step that opens the PR | Your team's pipeline already owns PR creation as a policy | You want the PR opened immediately, in the same step as the commit |
FAQs
Do I need to tell Claude Code the exact gh command to run?
No - you can ask in plain language ("commit this and open a PR"), and Claude Code runs the equivalent git and gh commands itself; knowing the underlying commands just helps you understand and verify what it did.
What base branch does gh pr create target by default?
The repository's configured default branch, usually main or master, unless you pass --base to target something else.
Can I open a draft PR instead of a ready-for-review one?
Yes, add --draft to gh pr create; draft PRs don't request reviews automatically and signal the work is still in progress.
What happens if the branch already has an open PR?
gh pr create will tell you a PR already exists for that branch and won't create a duplicate; use gh pr view to see the existing one instead.
Does gh pr create run any CI checks automatically?
Opening the PR triggers whatever GitHub Actions workflows are configured to run on pull_request events in the repository - gh itself doesn't run checks directly.
Can I specify reviewers when creating the PR?
Yes, with --reviewer <username> (or a team handle); you can pass it multiple times for more than one reviewer.
Is there a way to preview the PR before it's actually created?
gh pr create has an interactive mode that shows a preview and asks for confirmation when you omit --title/--body; scripted usage skips that preview by supplying both flags directly.
What if my commit message is long and multi-line?
Use a heredoc for the -m flag's argument, the same technique shown for --body in the Working Example, so newlines are preserved correctly.
Does the PR title need to match the commit message?
No, they're independent - --title sets the PR's title explicitly regardless of what the commit messages say, unless you use --fill, which derives both from the commit history.
Can Claude Code open a PR against a fork instead of the origin repository?
Yes, gh pr create supports --repo to target a specific repository, which is how a PR gets opened from a fork back to the upstream project.
How do I confirm the PR was actually created successfully?
Check the command's printed URL, or run gh pr view immediately after, which prints the current branch's associated PR details if one exists.
What's the minimum I need installed for this to work?
Just the gh CLI, authenticated once via gh auth login, and a git repository with a GitHub remote configured - no additional Claude Code configuration is required.
Related
- GitHub Integration Basics - installing and authenticating the
ghCLI before using it in a session. - How Claude Code Fits Into Your GitHub Pull Request Workflow - where opening a PR sits relative to reviewing and responding to feedback.
- Responding to PR Review Comments Automatically - the natural next step once this PR receives feedback.
- GitHub Integration Best Practices - patterns for keeping session-opened PRs safe and reviewable.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5. Model names, pricing, and product features move quickly - verify current specifics at platform.claude.com/docs before relying on them.