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.
Search across all documentation pages
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.
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.
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:
#!/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:
$(cat <<'EOF' ... EOF)) to pass a multi-paragraph PR body without escaping issues.-u so the branch is tracked on the remote before gh pr create runs.gh pr view --json url instead of assuming the command succeeded.Fixes #482) so GitHub auto-links and closes the issue on merge.gh pr create reads the current branch's tracking information to determine what to push against, and the repository's default branch (usually main) as the PR's base unless --base is passed explicitly.git push -u origin HEAD handles that in one step by both pushing and setting up tracking.--title and --body are optional; omitting them drops gh into an interactive prompt, which is why session-driven usage almost always supplies both explicitly.gh pr create prints the new PR's URL to stdout, which is useful for a session to report back to you.gh authenticates using the token stored by gh auth login, the same credential used for every other gh subcommand.| 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. |
# --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 --fillgh pr create. gh pr create needs the branch to exist on the remote first; if you skip git push -u origin HEAD, the command fails asking you to push. Fix: always push with -u immediately before creating the PR, or let --fill's prompt push it for you.main against main doesn't make sense - gh pr create will error or behave unexpectedly. Fix: create and check out a feature branch (git checkout -b <branch-name>) before making changes.gh auth token. Commands silently fail with an authentication error if gh auth login was never run or the token expired. Fix: run gh auth status first; re-authenticate with gh auth login if it reports not logged in.--body as 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.gh pr create opens 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: run git status or git branch --show-current immediately before creating the PR to confirm.Fixes #<number> or Refs #<number> in the body, and confirm the issue number before running the command.| 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 |
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.
The repository's configured default branch, usually main or master, unless you pass --base to target something else.
Yes, add --draft to gh pr create; draft PRs don't request reviews automatically and signal the work is still in progress.
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.
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.
Yes, with --reviewer <username> (or a team handle); you can pass it multiple times for more than one reviewer.
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.
Use a heredoc for the -m flag's argument, the same technique shown for --body in the Working Example, so newlines are preserved correctly.
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.
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.
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.
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.
gh CLI before using it in a session.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.
Reviewed by Chris St. John·Last updated Jul 18, 2026