ワンクリックで
github-pr-workflow
GitHub PR lifecycle: branch, commit, open, CI, merge.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
GitHub PR lifecycle: branch, commit, open, CI, merge.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Orchestrate Daimon specialists in Aether Agents — delegation, monitoring, Pure Orchestrator pattern, cost optimization, and common pitfalls.
Delegate tasks to specialist Daimons — decompose, delegate, monitor, and report results.
Configure, extend, or contribute to Hermes Agent.
Design and rework Aether Agents Daimon profiles — SOUL.md, config.yaml, toolset selection, and agent type taxonomy. Covers the full rework cycle from role definition to implementation.
Design HTML UI artifacts — from rapid multi-variant mockups (sketches) to polished single-artifact landing pages, decks, and prototypes. Includes design theology, anti-slop rules, and comparison workflows.
Kanban multi-agent orchestration — decomposition playbook for orchestrators, pitfalls and handoff shapes for workers, and the full task lifecycle.
| name | github-pr-workflow |
| description | GitHub PR lifecycle: branch, commit, open, CI, merge. |
| version | 1.5.0 |
| author | Hermes Agent |
| license | MIT |
| metadata | {"hermes":{"tags":["GitHub","Pull-Requests","CI/CD","Git","Automation","Merge"],"related_skills":["github-auth","github-code-review"]}} |
Complete guide for managing the PR lifecycle. Each section shows the gh way first, then the git + curl fallback for machines without gh.
github-auth skill)# Determine which method to use throughout this workflow
if command -v gh &>/dev/null && gh auth status &>/dev/null; then
AUTH="gh"
else
AUTH="git"
# Ensure we have a token for API calls
if [ -z "$GITHUB_TOKEN" ]; then
if [ -f ~/.hermes/.env ] && grep -q "^GITHUB_TOKEN=" ~/.hermes/.env; then
GITHUB_TOKEN=$(grep "^GITHUB_TOKEN=" ~/.hermes/.env | head -1 | cut -d= -f2 | tr -d '\n\r')
elif grep -q "github.com" ~/.git-credentials 2>/dev/null; then
GITHUB_TOKEN=$(grep "github.com" ~/.git-credentials 2>/dev/null | head -1 | sed 's|https://[^:]*:\([^@]*\)@.*|\1|')
fi
fi
fi
echo "Using: $AUTH"
Many curl commands need owner/repo. Extract it from the git remote:
# Works for both HTTPS and SSH remote URLs
REMOTE_URL=$(git remote get-url origin)
OWNER_REPO=$(echo "$REMOTE_URL" | sed -E 's|.*github\.com[:/]||; s|\.git$||')
OWNER=$(echo "$OWNER_REPO" | cut -d/ -f1)
REPO=$(echo "$OWNER_REPO" | cut -d/ -f2)
echo "Owner: $OWNER, Repo: $REPO"
This part is pure git — identical either way:
# Make sure you're up to date
git fetch origin
git checkout main && git pull origin main
# Create and switch to a new branch
git checkout -b feat/add-user-authentication
Branching model note: This workflow assumes feature → main direct (no integration branch). If your team uses feature → dev → main, branch from dev instead. See references/branching-models.md for both models, migration guide, and when to use each.
Branch naming conventions:
feat/description — new featuresfix/description — bug fixesrefactor/description — code restructuringdocs/description — documentationci/description — CI/CD changesSome config files (e.g., home/config.yaml) are in .gitignore because they contain API keys or are machine-specific. If you need to commit a structural configuration change (like toolset definitions) that is not a secret, git add will silently skip it — no error, no warning, and the file won't appear in git status.
Detect: If git diff <file> and git status <file> show nothing but you know the file was modified, check .gitignore:
git ls-files <file> # empty = not tracked, possibly ignored
git check-ignore -v <file> # shows which rule ignores it
Fix: Force-track with -f:
git add -f path/to/ignored-file.yaml
Caution: Only force-track files whose content you've reviewed. Never force-add files that contain real secrets (hardcoded passwords, API keys as literal values). Files using ${ENV_VAR} references for secrets are safe to track.
Adding a file to .gitignore does NOT stop git from tracking changes to it if it was already committed. git add -A will happily stage modifications to a tracked file that matches .gitignore rules. This is a common source of accidentally committed secrets or runtime configs.
Detect: After staging, check for files that should be gitignored but appear in the diff:
# Show all staged files — scan for anything that should be local
git diff --cached --name-only
# Specifically check if a gitignored file is still tracked
git ls-files path/to/file.yaml # non-empty = still tracked
Fix: Remove from the index (keeps the local file):
git rm --cached path/to/local-config.yaml
git commit -m "chore: stop tracking local config (already in .gitignore)"
After git rm --cached, future git add -A will correctly skip the file.
When a project has accumulated runtime artifacts (SQLite databases, caches, session state, JSON dumps) that aren't in .gitignore, git add -A stages everything indiscriminately. Before committing any bulk staging:
git status --short and review ?? entries for runtime state.gitignore first — add patterns for any runtime files/dirs discovered (e.g., *.db, cache/, hindsight/, state-snapshots/, .curator_state)git add -A — newly gitignored files won't appearCommon runtime artifacts to exclude:
kanban.db, *.db-shm, *.db-wal — local databasescache/, state-snapshots/ — derived/cached datahindsight/, *.lock — session/temp state*.restart_*.json, .curator_state — daemon/runtime metadataUse the agent's file tools (write_file, patch) to make changes, then commit:
Before git add -A: audit untracked files for runtime state (see Pitfall 3). Update .gitignore first if needed, and git rm --cached any tracked files that should be gitignored (see Pitfall 2).
# Stage specific files (use -f for gitignored files you intentionally want to track)
git add src/auth.py src/models/user.py tests/test_auth.py
# Commit with a conventional commit message
git commit -m "feat: add JWT-based user authentication
- Add login/register endpoints
- Add User model with password hashing
- Add auth middleware for protected routes
- Add unit tests for auth flow"
Commit message format (Conventional Commits):
type(scope): short description
Longer explanation if needed. Wrap at 72 characters.
Types: feat, fix, refactor, docs, test, ci, chore, perf
git push -u origin HEAD
With gh:
gh pr create \
--title "feat: add JWT-based user authentication" \
--body "## Summary
- Adds login and register API endpoints
- JWT token generation and validation
## Test Plan
- [ ] Unit tests pass
Closes #42"
Options: --draft, --reviewer user1,user2, --label "enhancement", --base develop
With git + curl:
BRANCH=$(git branch --show-current)
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/$OWNER/$REPO/pulls \
-d "{
\"title\": \"feat: add JWT-based user authentication\",
\"body\": \"## Summary\nAdds login and register API endpoints.\n\nCloses #42\",
\"head\": \"$BRANCH\",
\"base\": \"main\"
}"
The response JSON includes the PR number — save it for later commands.
To create as a draft, add "draft": true to the JSON body.
With gh:
# One-shot check
gh pr checks
# Watch until all checks finish (polls every 10s)
gh pr checks --watch
With git + curl:
# Get the latest commit SHA on the current branch
SHA=$(git rev-parse HEAD)
# Query the combined status
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
print(f\"Overall: {data['state']}\")
for s in data.get('statuses', []):
print(f\" {s['context']}: {s['state']} - {s.get('description', '')}\")"
# Also check GitHub Actions check runs (separate endpoint)
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/check-runs \
| python3 -c "
import sys, json
data = json.load(sys.stdin)
for cr in data.get('check_runs', []):
print(f\" {cr['name']}: {cr['status']} / {cr['conclusion'] or 'pending'}\")"
# Simple polling loop — check every 30 seconds, up to 10 minutes
SHA=$(git rev-parse HEAD)
for i in $(seq 1 20); do
STATUS=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/commits/$SHA/status \
| python3 -c "import sys,json; print(json.load(sys.stdin)['state'])")
echo "Check $i: $STATUS"
if [ "$STATUS" = "success" ] || [ "$STATUS" = "failure" ] || [ "$STATUS" = "error" ]; then
break
fi
sleep 30
done
When reviewing multiple PRs and all show the same CI failure pattern, verify whether the failure already exists on main before writing the PR off:
# Check if main branch CI also fails with the same check
gh run list --branch main --limit 1 --json conclusion,workflowName
# View the failed log from main for comparison
gh run view <RUN_ID> --log-failed | grep -E "error|failure|exit code" | head -10
# Cross-reference the same check name on the PR branch
gh pr checks <PR_NUMBER> --json name,description,state
Decision logic for pre-existing failures:
| Main CI | PR CI | Assessment |
|---|---|---|
| ✅ passing | ❌ failing | Likely introduced by PR — do NOT merge until fixed |
| ❌ failing | ❌ failing (same error) | Pre-existing — failure existed before the PR. Safe to merge if PR changes are orthogonal to the failing checks |
| ❌ failing | ✅ passing | PR fixed or bypassed a broken check — unusual, verify manually |
| ❌ failing | ❌ failing (different error) | Mixed — verify PR didn't add new failures on top of pre-existing ones |
Confirming orthogonality: If the PR touches only docs, config templates, setup scripts, or skill files — and the CI failure is a lint error in src/ or a unit test in a module the PR never touched — the failure is orthogonal and pre-existing.
Pitfall — don't merge when in doubt: If you can't tell whether the CI failure is pre-existing or introduced, treat it as blocking. Run the failing CI step on the PR branch directly (gh run view --log-failed) and compare the error to a fresh run on main.
When CI fails, diagnose and fix. This loop works with either auth method.
With gh:
# List recent workflow runs on this branch
gh run list --branch $(git branch --show-current) --limit 5
# View failed logs
gh run view <RUN_ID> --log-failed
With git + curl:
BRANCH=$(git branch --show-current)
# List workflow runs on this branch
curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
"https://api.github.com/repos/$OWNER/$REPO/actions/runs?branch=$BRANCH&per_page=5" \
| python3 -c "
import sys, json
runs = json.load(sys.stdin)['workflow_runs']
for r in runs:
print(f\"Run {r['id']}: {r['name']} - {r['conclusion'] or r['status']}\")"
# Get failed job logs (download as zip, extract, read)
RUN_ID=<run_id>
curl -s -L \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/actions/runs/$RUN_ID/logs \
-o /tmp/ci-logs.zip
cd /tmp && unzip -o ci-logs.zip -d ci-logs && cat ci-logs/*.txt
After identifying the issue, use file tools (patch, write_file) to fix it:
git add <fixed_files>
git commit -m "fix: resolve CI failure in <check_name>"
git push
Re-check CI status using the commands from Section 4 above.
When asked to auto-fix CI, follow this loop:
read_file + patch/write_file → fix the codegit add . && git commit -m "fix: ..." && git pushWith gh:
# Squash merge + delete branch (cleanest for feature branches)
gh pr merge --squash --delete-branch
# Enable auto-merge (merges when all checks pass)
gh pr merge --auto --squash --delete-branch
With git + curl:
PR_NUMBER=<number>
# Merge the PR via API (squash)
curl -s -X PUT \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER/merge \
-d "{
\"merge_method\": \"squash\",
\"commit_title\": \"feat: add user authentication (#$PR_NUMBER)\"
}"
# Delete the remote branch after merge
BRANCH=$(git branch --show-current)
git push origin --delete $BRANCH
# Switch back to main locally
git checkout main && git pull origin main
git branch -d $BRANCH
Merge methods: "merge" (merge commit), "squash", "rebase"
# Auto-merge requires the repo to have it enabled in settings.
# This uses the GraphQL API since REST doesn't support auto-merge.
PR_NODE_ID=$(curl -s \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/repos/$OWNER/$REPO/pulls/$PR_NUMBER \
| python3 -c "import sys,json; print(json.load(sys.stdin)['node_id'])")\n
curl -s -X POST \
-H "Authorization: token $GITHUB_TOKEN" \
https://api.github.com/graphql \
-d "{\"query\": \"mutation { enablePullRequestAutoMerge(input: {pullRequestId: \\\"$PR_NODE_ID\\\", mergeMethod: SQUASH}) { clientMutationId } }\"}"
gh pr review --approve fails with: GraphQL: Review Can not approve your own pull request. This happens when the authenticated GitHub user is also the PR author.
Solution: If you have merge permissions on the repo and no external review is required by branch protection rules, skip the approval step entirely and proceed directly to merge:
# Instead of: gh pr review N --approve && gh pr merge N --squash --delete-branch
# Just merge directly:
gh pr merge N --squash --delete-branch
Detection: Before attempting approve, check if the PR author matches the authenticated user:
PR_AUTHOR=$(gh pr view N --json author --jq .author.login)
GH_USER=$(gh api user --jq .login)
if [ "$PR_AUTHOR" = "$GH_USER" ]; then
echo "Self-PR detected: skipping approval, merging directly"
gh pr merge N --squash --delete-branch
else
gh pr review N --approve
gh pr merge N --squash --delete-branch
fi
When there are local uncommitted modifications, gh pr merge may produce a confusing partial result:
git checkout, branch deletion, and git pull all abortMERGED but the local repo is on the old branch with dirty stateFix — before merging: Always check and stash local changes first:
if [ -n "$(git status --porcelain)" ]; then
git stash push -m "pre-merge-autostash"
gh pr merge N --squash --delete-branch
git stash pop
else
gh pr merge N --squash --delete-branch
fi
Recovery if you already merged and the local step failed:
# Delete the remote branch manually (the API merge already happened)
git push origin --delete <feature-branch>
# Switch to main and sync
git stash # or commit local changes
git checkout main
git pull origin main
# Restore local changes
git stash pop
# Verify the remote branch was deleted
git fetch --prune origin
# 1. Start from clean main
git checkout main && git pull origin main
# 2. Branch
git checkout -b fix/login-redirect-bug
# 3. (Agent makes code changes with file tools)
# 4. Commit
git add src/auth/login.py tests/test_login.py
git commit -m "fix: correct redirect URL after login
Preserves the ?next= parameter instead of always redirecting to /dashboard."
# 5. Push
git push -u origin HEAD
# 6. Create PR (picks gh or curl based on what's available)
# ... (see Section 3)
# 7. Monitor CI (see Section 4)
# 8. Merge when green (see Section 6)
Complete versioned release pipeline: branch → changes → commit → tag → PR → merge → release.
# Start from clean main
git checkout main && git pull origin main
# Create release branch
git checkout -b release/v0.8.0
# Bump version in pyproject.toml, CHANGELOG.md, AGENTS.md, etc.
# (Delegate to Hefesto or make changes directly)
# Stage ONLY intended files — never git add -A in repos with runtime data
git add pyproject.toml CHANGELOG.md AGENTS.md README.md scripts/ Makefile
git commit -m "release: v0.8.0 — automated setup scripts, docs overhaul"
# Create annotated tag
git tag v0.8.0
# Push branch + tag
git push origin release/v0.8.0 --tags
# Create PR targeting main
gh pr create \
--base main \
--head release/v0.8.0 \
--title "release: v0.8.0 — description" \
--body "## v0.8.0 — Title
### What's New
- feat: new feature description
### Breaking Changes
- None (or description)
### Migration from v0.7.x
- Run bash scripts/setup.sh"
# Squash merge + delete branch (cleanest for releases)
gh pr merge 25 --squash --delete-branch
gh release create v0.8.0 \
--title "v0.8.0 — Title" \
--notes "## v0.8.0 — Title
### Quick Start
\`\`\`bash
git clone https://github.com/OWNER/REPO.git
cd REPO
bash scripts/setup.sh
\`\`\`
### What's New
- bullet points
### Upgrade from v0.7.x
- Migration instructions"
# Switch back to main and pull the merge
git checkout main
git pull origin main
# Delete local branch (remote already deleted by --delete-branch)
git branch -d release/v0.8.0
After any release that removes files, changes installation method, moves paths, or deprecates commands, run a string audit BEFORE tagging. This is a scoped version of the general post-migration audit (see autonomous-ai-agents/hermes-agent/references/post-migration-audit.md for the full methodology).
Quick audit — version consistency and dangling references:
# 1. Find references to deleted/moved files in tracked content
git ls-files | xargs grep -l 'configure\.sh\|start\.sh\|olympus_v2\|\.pi-daimons\|~/.hermes/' 2>/dev/null
# 2. Find paths that should be placeholders
grep -rn '/home/[^/]\+/Aether-Agents' --include='*.md' --include='*.yaml' --include='*.html' 2>/dev/null | grep -v '.template'
# 3. Check version badge matches across ALL version-carrying files
grep 'version' pyproject.toml | head -1
grep 'version-' README.md | head -1
grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' CHANGELOG.md | head -1
grep -o 'v[0-9]\+\.[0-9]\+\.[0-9]\+' Makefile scripts/setup.sh | sort | uniq -c # easy to miss
# 4. Check CI action versions aren't outdated
grep -rn 'uses:.*@v[0-9]' .github/workflows/
# 5. Check website references (if applicable)
grep -rn 'pip install -e \.\|configure\.sh\|start\.sh\|~/.hermes/' website/ 2>/dev/null
Full migration audit — after path changes, convention shifts, or module renames:
For major refactoring (.eter/ → .aether/, profile restructuring, script renaming), follow the comprehensive post-migration audit methodology: catalog old conventions, grep for each pattern, classify by priority (functional code > agent configs > docs > CHANGELOG), fix in order, migrate on-disk state, verify clean. See references/post-migration-audit.md in the hermes-agent skill.
Fix all findings, commit, then proceed with tagging.
git add -A: Stage specific files only. Repos with runtime data (databases, sessions, caches, local configs) will stage everything. Use git add <file1> <file2> ... or git diff --cached --stat to review before committing.--squash --delete-branch for release PRs. This keeps main history clean with a single commit per release. Feature branches can use regular merge if needed.git checkout or git merge will abort if local modifications would be overwritten. Always git status --short before branch operations. Stash (git stash push), commit, or discard changes first. See references/branching-models.md for the full pattern.
|- Backup recovery with wrong directory structure: When cherry-picking from an old backup branch, the directory structure may have changed (e.g., home/skills/ in backup vs skills/ in current HEAD). Extract content to the CURRENT structure, not the backup's structure. Verify destination paths before writing. See references/branching-models.md.Síntoma: Ejecutas gh pr review <N> --approve en un PR abierto por ti mismo (DarkArty07). GitHub rechaza con error gh: Cannot approve your own pull request. El merge con gh pr merge --squash SÍ funciona sin aprobación, pero queda sin audit trail de review.
Por qué: Regla de GitHub — un usuario no puede aprobar su propio PR. gh pr review --approve falla con 422 si el revisor es el autor.
Opciones para batch self-merge:
Aceptar el merge sin aprobación (lo que hicimos en sesión 06-04 con 5 PRs):
gh pr merge <N> --squash --delete-branch
Funciona si el PR es MERGEABLE y la branch protection no requiere review. Si requiere review, este comando falla con "Reviews required".
Configurar branch protection para permitir merge sin review (recomendado para repo personal):
Habilitar auto-approve con ruleset + GitHub Actions (más limpio):
.github/workflows/auto-approve.yml que aprueba PRs del ownerPara repos personales de un solo owner (caso de Aether): Opción 2 es la más limpia. Un solo toggle, sin CI, sin reglas.
Cuándo SÍ requerir review humano: Repo con colaboradores externos, código de producción sensible, cambios en CI/CD.
Audit trail alternativo: Si quieres saber que "alguien revisó" sin aprobación humana, usa gh pr view <N> --json reviews,comments post-merge para extraer el diff y los comentarios dejados. Pero sin gh pr review --approve, no hay línea formal de aprobación.
Síntoma: Tu repo tiene CI rojo en main (ej. Ruff lint con 28 errores en src/olympus_v3/server.py que ya existían antes de tu PR). Quieres mergear 5 PRs que NO tocan src/ — solo tocan home/skills/, docs/, scripts/, CHANGELOG.md. La tentación es no mergear ninguno hasta arreglar el lint.
Decisión correcta: Mergear las PRs que no tocan src/ y arreglar el lint en una PR separada de cleanup.
Por qué:
feature/fix-ruff-lint-server) es más fácil de revisar que un mega-PR que mezcla features con refactors de lint.Cómo identificar si el CI failure es pre-existente:
# En main, antes de mergear
git checkout main
gh pr checks <PR_NUMBER> 2>&1 | head -20
# Si el check fallido es del estilo "ruff lint failed on src/X.py" y main también tiene ese error:
git checkout main
.venv-hermes/bin/python -m ruff check src/X.py
# Si el error aparece aquí también → es pre-existente
Política recomendada para repo personal:
Naming convention para la PR de cleanup: feature/fix-ruff-lint-<module> o chore/fix-pre-existing-lint para que sea buscable después.
When git merge (or git pull which runs merge) encounters conflicting changes, git pauses and marks files as unmerged. The merge is incomplete — you must resolve before committing.
After a merge attempt:
git status
Look for these indicators:
| Status | Meaning |
|---|---|
both modified: <file> | modify/modify — same file changed in both branches |
both added: <file> | add/add — same file created in both branches |
deleted by us: <file> | deleted on current branch, modified on theirs |
deleted by them: <file> | modified on current branch, deleted on theirs |
Unmerged paths: section | Summary of files needing resolution |
All conflicts fixed but you are still merging. | All marked resolved, ready to commit |
During git merge <other> while on current-branch:
current-branch (the branch you're merging INTO)<other> (the branch being merged FROM)# Keep current branch's version
git checkout --ours path/to/file
# Keep the other branch's version
git checkout --theirs path/to/file
CRITICAL: These flags only work for files listed under Unmerged paths. For files listed under Changes not staged for commit (unstaged modifications that aren't part of the conflict), use git checkout origin/main -- path/to/file to reset to the remote's version.
This happens when the same file was created independently in both branches. Neither side may have the full content. Always inspect both versions:
git checkout --ours path/to/file # inspect current branch's version
git checkout --theirs path/to/file # inspect the other branch's version
Manual union strategy: When neither side alone has the complete desired content (e.g., each PR added different tests in the same file), you must manually construct the union:
--theirs or --ours) as the basepatch/write_file to add the missing content from the other sidegrep -c "def test_" to confirm total test count)git addSame file changed differently in both branches. The file on disk contains merge conflict markers:
<<<<<<< HEAD
// our version (current branch)
=======
// their version (branch being merged)
>>>>>>> branch-name
Resolution options:
# Accept one side entirely
git checkout --ours path/to/file # keep current branch's version
git checkout --theirs path/to/file # keep other branch's version
# Or edit the file manually to pick specific changes from both sides
# (remove the <<<<<<<, =======, >>>>>>> markers and keep the desired content)
Always verify the resolved file has correct content before staging:
# For test files: count test functions
grep -c "^def test_" tests/test_file.py
# Check for remaining conflict markers (bad!)
grep -rn "<<<<<<< \|=======\|>>>>>>>" path/to/file
# For modify/modify: ensure expected content is present
grep "specific_function_or_import" path/to/file
# Show the resolved diff
git diff path/to/file
# Stage resolved files — only the ones you resolved
git add path/to/file1 path/to/file2
# Verify staging
git status
git diff --cached --name-status
# Complete the merge (auto-generates a merge commit message)
git commit --no-edit
# Or write a custom message
git commit -m "Merge branch 'main' into feature/my-feature"
Always verify the actual state on disk rather than blindly trusting instructions. The task may say --theirs but the context may contradict it. Cross-check:
git status--ours then --theirs)Neither side may be "correct" — both branches may have added different subsets of the same logical file. The guardrail "if checkout resolves to wrong version, stop" is useful, but the better response is to manually merge both versions rather than reporting failure.
A file showing as modified under "Changes not staged for commit" during a merge is NOT part of the conflict — it's an unrelated working-tree change. Do NOT use git checkout --ours/--theirs on it. Use git checkout origin/main -- <file> to reset it.
| Action | gh | git + curl |
|---|---|---|
| List my PRs | gh pr list --author @me | curl -s -H "Authorization: token $GITHUB_TOKEN" "https://api.github.com/repos/$OWNER/$REPO/pulls?state=open" |
| View PR diff | gh pr diff | git diff main...HEAD (local) or curl -H "Accept: application/vnd.github.diff" ... |
| Add comment | gh pr comment N --body "..." | curl -X POST .../issues/N/comments -d '{"body":"..."}' |
| Request review | gh pr edit N --add-reviewer user | curl -X POST .../pulls/N/requested_reviewers -d '{"reviewers":["user"]}' |
| Close PR | gh pr close N | curl -X PATCH .../pulls/N -d '{"state":"closed"}' |
| Check out someone's PR | gh pr checkout N | git fetch origin pull/N/head:pr-N && git checkout pr-N |
references/conventional-commits.md — Commit message format and type referencereferences/ci-troubleshooting.md — Common CI failure patterns and fixesreferences/branching-models.md — When to use feature → dev → main vs feature → main, migration guide, stash patterns, and backup recovery pitfallsreferences/smoke-testing-setup-scripts.md — Single-PR fresh-clone smoke test for setup script changesreferences/multi-pr-smoke-test-remote.md — Multi-PR consolidated smoke test on a remote machine via SSH; check() function pattern, submodule cloning pitfalls, eval + cd side effects, exec > >(tee) buffering over SSH, and broad grep false positivesreferences/batch-pr-cleanup.md — Multi-PR autonomous sweep checklist: discovery, classification, self-approval bypass, pre-existing CI detection, batch execution, post-merge sync, and anti-patterns