gh-pr
Open a GitHub pull request (draft or ready for review) from the current branch using the gh CLI.
Skill by Dzhuneyt
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/dzhuneyt-gh-pr
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/gh-pr
What's inside
- Skill name
gh-pr- Description
- Open a GitHub pull request (draft or ready for review) from the current branch using the gh CLI. Use this whenever the user wants to open, create, raise, submit, or "ship" a PR / pull request, or says things like "open a PR", "PR this branch", "put this up for review", or invokes /gh-pr — even when they don't specify the base branch, title, or description. Handles pushing the branch, writing the title and body from the actual diff, respecting the repo's PR template, linking issues, and dropping to --draft for unfinished work.
- License
- MIT
- Instructions
- 264 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# gh-pr
Open a pull request from the current branch with a title and body that reflect what actually changed, not just the last commit message. The goal is a PR a reviewer can understand without reading the diff first.
Use `gh` for everything. It handles auth, the API, and returns a URL at the end. Do not script raw API calls.
## The shape of the work
Three phases, in order. The hard rule that drives the ordering: **nothing gets pushed until the work is confirmed to be on the right branch.** Phase 2 is entirely local and reversible; the first irreversible-ish action (push) is the top of Phase 3.
```
Phase 1 Can I run? local gates + gh auth
any gate fails -> stop
|
v
Phase 2 Right place? base -> assess -> branch-fit -> settle tree
all local, nothing pushed yet
|
v
Phase 3 Open the PR push -> compose -> gh pr create -> url
```
---
# PHASE 1 · Can I run?
## Step 0: cheap local gates
All local — no network, no push — so they fail in milliseconds before any expensive work. Order matters: cheapest and most fundamental first.
**Hard exits** — nothing downstream can recover, so bail immediately with a clear message:
1. **Not a git repo.** `git rev-parse --is-inside-work-tree`. Fastest check; run it first.
2. **`gh` not installed.** `command -v gh`. The cheap, local half of the auth check — keep it separate from `gh auth status` (network, see Preflight). "Not installed" and "not logged in" need different messages.
3. **No `origin` remote.** `git remote get-url origin` (non-zero exit = no `origin`). This skill assumes a single remote named `origin` and pushes the branch there; with no `origin` there's nowhere to push and nothing for `gh` to target, so stop here. **Fork workflows are out of scope** — pushing to a fork while basing the PR against an `upstream` repo (`--head owner:branch`) is deliberately not handled. If the only remote is named something else (e.g. `upstream`), stop and ask rather than guessing.
4. **Remote isn't GitHub.** `git remote get-url origin`, check the host. GitLab/Bitbucket/anything else → `gh` can't help, stop here.
5. **Detached HEAD or unborn branch.** `git symbolic-ref -q HEAD` (empty = detached; also catches a fresh repo with no commits). No branch means nothing to PR.
**Confirm and stop** — possible but almost always a mistake, so pause rather than refuse:
6. **On the default branch.** A PR from `main` into `main` is almost always wrong. Cheap path: if `git symbolic-ref refs/remotes/origin/HEAD` resolves locally (it only exists when the clone set `origin/HEAD`, e.g. via `git remote set-head origin -a`), compare against it here. If it's missing, skip the check here — Preflight resolves the default branch authoritatively and re-checks.
7. **Mid-operation.** Check for `MERGE_HEAD`, `.git/rebase-merge`, `.git/rebase-apply`, `.git/CHERRY_PICK_HEAD`, `.git/REVERT_HEAD`. A rebase/merge/cherry-pick/revert in flight means the tree is half-applied — a PR now is garbage.
8. **Zero commits ahead of base.** A smoke test only — base isn't resolved yet (that's Phase 2). Compare against the locally-resolved default branch (the `origin/HEAD` target from Step 0's default-branch check; skip if that ref is missing) using `git rev-list --count origin/<default>..HEAD`. **Before treating zero as a bail, check `git status --porcelain`:** a dirty tree means the work exists but is uncommitted — don't exit; carry on to Phase 2 and let "Settle uncommitted changes" commit it. Only zero commits + clean tree is a true hard exit. Phase 2 authoritatively determines the base (including any user-specified base) and supersedes this check; a non-zero count here is not a guarantee against the real base, and `origin/<default>` may be locally stale.
Once Step 0 passes, `git branch --show-current` gives the head branch for everything below.
## Preflight (network)
Costs a round trip, so it runs only after Step 0 clears.
- `gh auth status` — confirm the CLI is authenticated. If not, point the user at `gh auth login`; do not log in for them.
- **Resolve the default branch once, here.** Everything downstream (the Step 0 default-branch check, the base in Phase 2) refers back to this single value. Fallback chain — first hit wins:
1. `git symbolic-ref --short refs/remotes/origin/HEAD` → strip the `origin/` prefix (local, no round trip).
2. `gh repo view --json defaultBranchRef --jq .defaultBranchRef.name` (authoritative, one round trip).
If Step 0's local check was skipped because `origin/HEAD` was missing, re-check now that the head branch isn't this default.
---
# PHASE 2 · Is the work in the right place?
Everything in this phase is local. Resolve all of it before pushing.
## Determine the base branch
Reuse the default branch already resolved in Preflight — don't resolve it again. Use that default unless the user named a different base. Stacked PRs (a feature branch targeting another feature branch) are real but rare — the user usually says so. When in doubt, ask rather than assume `main`.
## Assess local state
Gather the facts once; they feed both the branch-fit decision and the PR body.
First resolve the upstream once, because the default first-PR path has none — the branch has never been pushed, so `origin/<branch>` doesn't exist and any `origin/<branch>..HEAD` comparison errors out:
```bash
git rev-parse --abbrev-ref @{u} 2>/dev/null # upstream, or empty
```
- **Upstream exists** → unpushed commits are `git log --oneline @{u}..HEAD`.
- **No upstream** (first PR) → there's nothing to compare against; treat *every* commit since base as unpushed and skip the `origin/<branch>` comparisons entirely.
```bash
git status --porcelain # dirty tree?
git log --reverse --format='%s%n%b' origin/<base>..HEAD # commits since base
git diff --stat origin/<base>...HEAD # files + scope
gh pr list --head <branch> --state open --json number,url,title # open PR?
```
The **local-only delta** = unpushed commits + uncommitted changes. That's the work that isn't yet captured anywhere — and it's the thing the branch-fit check reasons about. On the first-PR path every commit since base is part of that delta.
## Branch-fit decision
The failure mode: the user finished feature A (maybe already PR'd), started feature B without switching branches, and is now about to push B's work onto A.
Do **not** anchor on "does the branch name match the diff." Generic/personal names (`dev`, `wip`, `dzh/misc`) match nothing and false-positive constantly, and branches legitimately grow scope. Anchor on whether the branch already has a PR and whether there's local-only work on top of it:
```
open PR on branch? local-only delta? -> action
-----------------------------------------------------------------
no either open a fresh PR
yes none nothing new -> stop
yes some STOP and ask (below)
```
Only the last row stops a routine flow. In that case summarize the **delta only** (not the whole branch), e.g. "Branch `<branch>` already has open PR #123. You have 2 unpushed commits and 4 changed files since then — do these belong on this branch, or should they move to their own branch?"
Keep this gate high-precision. If it interrupts routine PRs with "are you sure you're on the right branch?", the user learns to mash through it and it stops being useful. Only the bottom-right cell stops the flow.
## If the work needs to move
The remedy forks on committed vs uncommitted, because the mechanics and risk differ sharply:
```
move the work off this branch:
uncommitted -> git switch -c <new> origin/<base> safe, just do it
(then continue — PR opens from <new>)
committed -> git switch -c <new> origin/<base> you do this
cherry-pick the stray commits onto <new>
...then reset old branch + force-push user's call — STOPFrom Dzhuneyt/skills, MIT.
More from Dzhuneyt/skills
- 0.565score
md-normaliser
Dzhuneyt
Normalises Markdown formatting in a repository — heading levels, list markers, trailing whitespace, and final newlines.
SkillAFreshness: AClaude Code +9 - 0.565score
notes-backup
Dzhuneyt
Backs up the user's Markdown notes folder to a remote store and restores it on another machine.
SkillAFreshness: AClaude Code +9 - 0.565score
changelog-writer
Dzhuneyt
Drafts a CHANGELOG entry from recent git commits.
SkillAFreshness: AClaude Code +9 - 0.560score
table-formatter
Dzhuneyt
Formats markdown tables.
SkillAFreshness: AClaude Code +9 - 0.559score
weather-brief
Dzhuneyt
Gives a short weather briefing for a city using the free Open-Meteo API.
SkillAFreshness: AClaude Code +9 - 0.559score
python-tidy
Dzhuneyt
Formats and lints Python code with black and isort, and checks that imported HTTP calls have timeouts.
SkillAFreshness: AClaude Code +9 - 0.559score
tidy-imports
Dzhuneyt
Sorts and de-duplicates import statements in Python and TypeScript files.
SkillAFreshness: AClaude Code +9 - 0.559score
csv-cleaner
Dzhuneyt
Cleans CSV files by trimming whitespace, normalising headers, and removing empty rows.
SkillAFreshness: AClaude Code +9 - 0.520score
git-branch-cleanup
Dzhuneyt
Use when stale git branches pile up after pull requests merge — local branches marked [gone], squash-merged branches that `git branch --merged` does not list…
SkillBFreshness: BClaude Code +9 - 0.520score
gh-pr-review
Dzhuneyt
Use when user asks to review a pull request by number, URL, or branch ("review this PR", "review PR 123").
SkillBFreshness: BClaude Code +9 - 0.474score
gh-notifications
Dzhuneyt
Use when user wants to review, triage, or surface important GitHub notifications — daily digest, notification fatigue, or "what should I look at?"
SkillCFreshness: CClaude Code +9 - 0.474score
apple-reminders
Dzhuneyt
Use when user asks to manage Apple Reminders on macOS — create, list, update, complete, or delete reminders and lists via osascript/AppleScript.
SkillCFreshness: CClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 1
- Last commit (this folder)
- Aug 5, 2026 (2 months ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/Dzhuneyt/skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from Dzhuneyt
- 0.565score
changelog-writer
Dzhuneyt
Drafts a CHANGELOG entry from recent git commits.
SkillAFreshness: AClaude Code +9 - 0.565score
notes-backup
Dzhuneyt
Backs up the user's Markdown notes folder to a remote store and restores it on another machine.
SkillAFreshness: AClaude Code +9 - 0.565score
md-normaliser
Dzhuneyt
Normalises Markdown formatting in a repository — heading levels, list markers, trailing whitespace, and final newlines.
SkillAFreshness: AClaude Code +9 - 0.560score
table-formatter
Dzhuneyt
Formats markdown tables.
SkillAFreshness: AClaude Code +9 - 0.559score
tidy-imports
Dzhuneyt
Sorts and de-duplicates import statements in Python and TypeScript files.
SkillAFreshness: AClaude Code +9 - 0.559score
weather-brief
Dzhuneyt
Gives a short weather briefing for a city using the free Open-Meteo API.
SkillAFreshness: AClaude Code +9
Cite this page
gh-pr skill. Agent Mart. https://agentmart.dev/skills/dzhuneyt-gh-pr (last updated 2026-10-24)