Merging the wrong pull request can trigger a deployment before anyone notices, so gh pr deserves the same care as any other production command. This guide takes a local branch through the full lifecycle: inspect it, open the pull request, check it, then merge it on purpose.
These examples match the installed gh version 2.87.3, released 23 February 2026. Allow about 10 minutes if your branch and authentication are ready. You need a Git repository and a GitHub account with access to its remote. Throughout, OWNER/REPO is a placeholder, swap in something real such as acme/widgets before running anything.
Start read-only, to confirm where you are before anything creates or changes state on GitHub:
$ git status --short --branch
$ gh pr status --repo OWNER/REPO
The first command should show the branch you intend to publish. Clean is easiest to reason about, but uncommitted files are not automatically a problem for every operation; just do not open a pull request until the intended changes are committed and the branch tracks the right upstream.
Checkpoint: wrong branch or repository named? Stop and fix that locally first. The --repo option accepts [HOST/]OWNER/REPO, so it also works with a GitHub Enterprise host.
List the repository's open pull requests, then look closely at the one you care about:
$ gh pr list --repo OWNER/REPO --state open --limit 20
$ gh pr view 123 --repo OWNER/REPO
$ gh pr diff 123 --repo OWNER/REPO
Swap in the real pull request number for 123. A pull request can also be addressed by its full URL or head branch name. gh pr list defaults to open pull requests and fetches at most 30; naming both state and limit explicitly keeps scripts and repeat checks predictable.
For a machine-readable check, ask for specific JSON fields:
$ gh pr view 123 --repo OWNER/REPO --json number,title,state,isDraft,statusCheckRollup
Field values vary with the repository. A missing or pending check is not the same thing as a passing one.
Commit your branch, push it if needed, and create the pull request with an explicit title and body:
$ git push --set-upstream origin FEATURE-BRANCH
$ gh pr create --repo OWNER/REPO --base main --head FEATURE-BRANCH \
--title "Describe the change briefly" \
--body "Explain the change, testing, and any rollout risk."
On success, gh pr create prints the new pull request URL. Omit --head and it defaults to the current branch; omit --base and it defaults to the repository's default branch. Naming both avoids a pull request aimed at the wrong target.
--head explicitly to sidestep that choice.Recovery: creating a pull request is a remote state change. Opened the wrong one? Do not merge it while trying to tidy up. Close it with gh pr close 123 --repo OWNER/REPO, then confirm with gh pr view 123 --repo OWNER/REPO --json state. Closing does not delete the branch or undo any commits.
Refresh the pull request's details and checks before you pick a merge strategy:
$ gh pr checks 123 --repo OWNER/REPO
$ gh pr view 123 --repo OWNER/REPO --comments
A passing gh pr checks result is evidence about what GitHub reports, not a substitute for reading the diff yourself. Pending or failing checks mean investigate and push a fix before merging, not merge and hope. Only add a review when you actually have the authority and intent to change the pull request's review state:
$ gh pr review 123 --repo OWNER/REPO --approve
Review options can approve, request changes or just comment. Treat approval as a recorded repository action, not a private note to yourself.
Warning: merging changes the base branch and can trigger deployments. Pick the repository's permitted strategy first, the ordinary options are merge, rebase and squash:
$ gh pr merge 123 --repo OWNER/REPO --squash
Prompted for confirmation? Read the target and strategy before answering. For an unattended run, --auto asks GitHub to merge once required conditions are met, it does not bypass them. --admin is different: an elevated action that bypasses normal requirements, so use it only under an explicit administrative decision.
Warning: do not add --delete-branch casually. It removes the local and remote pull request branch right after the merge. Need the branch for recovery? Leave the flag out. If it is already gone and the commits are still reachable in the merged history, recreate a local branch from a known commit:
$ git switch -c RECOVERED-BRANCH COMMIT_SHA
Otherwise recover the commit from another clone or the reflog before garbage collection catches up with it.
To stop an unexpectedly updated pull request from merging under you, pin the head commit:
$ gh pr view 123 --repo OWNER/REPO --json headRefOid
$ gh pr merge 123 --repo OWNER/REPO --squash --match-head-commit HEAD_SHA
Replace HEAD_SHA with the exact value the first command returned. If the head moved in the meantime, the merge is refused and you get a fresh look before trying again.
After a successful merge, check both the pull request state and your local branch:
$ gh pr view 123 --repo OWNER/REPO --json state,mergedAt,mergeCommit
$ git status --short --branch
Checkpoint: expect state to read MERGED with a populated merge timestamp. A clean local status proves nothing about the remote deployment; follow the repository's normal release or environment checks separately for that.
MERGED, or stays open with the reason on record.