Agent Skills: Get base branch SHA

Create PRs via GitHub API without local git operations. Use when you want to submit file changes as a PR without committing locally — for quick fixes, typos, config updates, or when you want a clean workflow that bypasses local git state entirely.

UncategorizedID: laurigates/claude-plugins/git-api-pr

Install this agent skill to your local

pnpm dlx add-skill https://github.com/laurigates/claude-plugins/tree/HEAD/git-plugin/skills/git-api-pr

Skill Files

Browse the full folder contents for git-api-pr.

Download Skill

Loading file tree…

git-plugin/skills/git-api-pr/SKILL.md

Skill Metadata

Name
git-api-pr
Description
Create PRs via GitHub API without local git operations. Use when you want to submit file changes as a PR without committing locally — for quick fixes, typos, config updates, or when you want a clean workflow that bypasses local git state entirely.

When to Use This Skill

| Use this skill when... | Use /git:commit instead when... | |------------------------|-----------------------------------| | Quick fix to 1-3 files (typos, config, docs) | Complex multi-file refactoring | | Want a clean workflow without local commits | Need local testing before submitting | | Submitting changes without touching git state | Need pre-commit hooks to run | | Want to avoid branch creation/switching locally | Need to stage partial file changes | | File edits are already done, just need the PR | Need interactive staging (git add -p) |

Context

  • Repo: !git remote get-url origin
  • Default branch: !git symbolic-ref refs/remotes/origin/HEAD
  • Auth: !gh auth status
  • Working dir: !pwd

Parameters

Parse these from $ARGUMENTS:

| Parameter | Required | Description | |-----------|----------|-------------| | $@ (positional) | Yes | One or more file paths to create/update in the repo | | --title <text> | Yes | PR title — use conventional commit format | | --base <branch> | No | Base branch (default: repo default branch from context) | | --branch <name> | No | New branch name (auto-generated from title if omitted) | | --body <text> | No | PR body/description | | --draft | No | Create as draft PR | | --delete | No | Delete the specified files instead of updating them |

Execution

Execute this server-side PR creation workflow:

Step 1: Validate inputs

  1. Parse file paths and flags from $ARGUMENTS
  2. Verify --title is provided — error if missing
  3. For each file path (unless --delete):
    • Verify the local file exists using Read tool
    • Resolve to a repo-relative path (strip leading ./ or working directory prefix)
  4. Determine the repo from context ($REPO)
  5. Determine base branch: use --base if provided, otherwise use default branch from context

Step 2: Resolve base branch state

# Get base branch SHA
BASE_SHA=$(gh api repos/$REPO/git/ref/heads/$BASE_BRANCH -q .object.sha)

# Get base tree SHA
BASE_TREE=$(gh api repos/$REPO/git/commits/$BASE_SHA -q .tree.sha)

If this fails, the base branch doesn't exist — report error and list available branches.

Step 3: Generate branch name (if --branch not provided)

Derive from the --title:

  1. Take the subject part (after type(scope): )
  2. Convert to kebab-case
  3. Prefix with the commit type (e.g., fix/kebab-subject)
  4. Example: "fix(api): handle null response"fix/handle-null-response

Step 4: Create blobs for each file

For each file path:

# Base64-encode the file content and create a blob
BLOB_SHA=$(gh api repos/$REPO/git/blobs \
  -f content="$(base64 < "$FILE_PATH" | tr -d '\n')" \
  -f encoding=base64 \
  -q .sha)

Track each {path, blob_sha} pair for the tree creation in Step 5.

For --delete files, skip blob creation — these are handled differently in the tree.

Step 5: Create tree with all file changes

Build a tree JSON payload and create the tree:

# Write tree entries to a temp file
TREE_FILE=$(mktemp)

For each file to update/create, add a tree entry:

{"path": "relative/path/to/file", "mode": "100644", "type": "blob", "sha": "<blob_sha>"}

For each file to delete, add a tree entry:

{"path": "relative/path/to/file", "mode": "100644", "type": "blob", "sha": null}

Create the tree:

TREE_SHA=$(gh api repos/$REPO/git/trees \
  -f base_tree="$BASE_TREE" \
  --input "$TREE_FILE" \
  -q .sha)

Note: The --input file must contain the full JSON body with a tree array. Example:

{
  "base_tree": "<BASE_TREE>",
  "tree": [
    {"path": "src/config.ts", "mode": "100644", "type": "blob", "sha": "<blob1>"},
    {"path": "README.md", "mode": "100644", "type": "blob", "sha": "<blob2>"}
  ]
}

Step 6: Create commit

COMMIT_SHA=$(gh api repos/$REPO/git/commits \
  -f message="$TITLE" \
  -f tree="$TREE_SHA" \
  -f "parents[]=$BASE_SHA" \
  -q .sha)

Step 7: Create branch ref

gh api repos/$REPO/git/refs \
  -f ref="refs/heads/$BRANCH" \
  -f sha="$COMMIT_SHA"

If this fails with "Reference already exists", report the error and suggest using a different branch name.

Step 8: Create PR

gh pr create \
  --repo "$REPO" \
  --head "$BRANCH" \
  --base "$BASE_BRANCH" \
  --title "$TITLE" \
  --body "${BODY:-"Created via API — no local git operations."}"

Add --draft if the flag was provided.

Step 9: Report results

Print a summary:

PR created successfully (no local git changes):
  PR:     <url>
  Branch: <branch> → <base>
  Files:  <count> file(s) changed
  Commit: <sha>

Cleanup

Remove any temp files created during execution.

Error Recovery

| Error | Recovery | |-------|----------| | gh auth status fails | "Run gh auth login first" | | Base branch SHA lookup fails | List branches: gh api repos/$REPO/branches --jq '.[].name' | | Blob creation fails | Report which file failed and the API error | | Branch already exists | Suggest --branch <different-name> | | Tree creation fails | Check if file paths are valid repo-relative paths | | PR creation fails | Show the API error — common cause is branch protection |

Agentic Optimizations

| Context | Command | |---------|---------| | Single file fix | /git:api-pr file.ts --title "fix: typo" | | Multi-file fix | /git:api-pr a.ts b.ts --title "fix: update configs" | | Draft PR | /git:api-pr file.ts --title "feat: wip" --draft | | Custom branch | /git:api-pr file.ts --title "fix: desc" --branch hotfix/issue-123 | | Delete file | /git:api-pr old-file.ts --title "chore: remove deprecated" --delete | | Non-default base | /git:api-pr file.ts --title "fix: desc" --base develop |

See Also

  • /git:commit — full local commit→push→PR workflow (use when you need pre-commit hooks, testing, or complex staging)
  • gh-cli-agentic — GitHub CLI patterns for JSON output and API access
  • git-branch-pr-workflow — branch management and PR workflow patterns