my-git-api

$npx mdskill add myapihq/myapi/my-git-api

Manage git repositories via CLI or real git over HTTPS.

  • Create repos, read history, and write commits without a local clone.
  • Uses go-git engine with GCS packfiles and Postgres for refs.
  • Accepts changes from directory, file, or JSON array for atomic commits.
  • Supports real git clone/push with API key as password over HTTPS.

SKILL.md

.github/skills/my-git-apiView on GitHub ↗
---
name: my-git-api
version: 1.0.0
description: >
  Hosted git repositories over HTTP. Create repos, read history (log/show/tree/blob/diff), and write atomically (commit/branch/tag/merge) — no clone needed. Real `git clone`/`push` also work over HTTPS with your API key as the password.
triggers: [git, repo, repository, clone, push, commit, branch, tag, merge, diff, version control, source control, vcs]
checksum: sha256-pending
---

# MyGitAPI

Per-org hosted git repositories, served by a go-git engine (objects in GCS packfiles, refs in Postgres). Two ways in: the `myapi git` CLI for clone-free reads and atomic writes, **or** a real `git clone`/`push` over HTTPS with HTTP Basic auth.

## Capabilities
<!-- llm:start -->
Git is the source-control layer. Each repo lives under your org and is reachable two ways:

1. **CLI / SDK** — no local clone. `commit` writes atomically from three sources: `--dir <path>` (every file under a local directory — the preferred path for committing a generated project), `--file <path> [--as <repo-path>]` (one local file), or an explicit `--changes` JSON array. Reads (`log`, `show`, `tree`, `blob`, `diff`, `refs`) round-trip the API.
2. **Real git over HTTPS** — `git clone`/`fetch`/`push` against `https://git.mygitapi.com/<org-slug>/<repo>.git` with your MyAPI API key as the password. This is how a normal git workflow connects (see *Clone & push with real git*).

Both surfaces share one engine: a `git push` and a `myapi git commit` converge on the same refs.

`commit --base <tip>` is optimistic concurrency — pass the expected branch tip to guard a write, or `--base ""` to require the branch not exist. `merge` is **fast-forward only**. `repack` compacts incremental packfiles into one.

`blob` prints a file's content (decoded) — it's a `cat`. `diff` needs `--base` and `--head`.
<!-- llm:end -->

## Commands
<!-- generated:start -->
| Command | What it does |
|---|---|
| `myapi git create <name>` | Create a repository (`--default-branch <b>`) |
| `myapi git list` | List repositories |
| `myapi git get <repo>` | Show branch/tag counts + default branch |
| `myapi git delete <repo>` | Delete a repository. Look before you delete: `myapi git list` first, pass `--org` explicitly; asks for confirmation — `--yes` required in non-interactive runs |
| `myapi git refs <repo>` | List HEAD, branches, and tags |
| `myapi git log <repo>` | List commits (`--ref`, `--limit`) |
| `myapi git show <repo> <sha>` | Show a single commit |
| `myapi git tree <repo> <ref>` | List a ref's file tree (`--path`) |
| `myapi git blob <repo> <ref> <path>` | Print a file's content (decoded) |
| `myapi git diff <repo>` | Unified diff of two refs (`--base`, `--head`) |
| `myapi git commit <repo>` | Atomic commit (`--branch`, `--message`, plus `--dir <path>` \| `--file <path> [--as <repo-path>]` \| `--changes <json>`) |
| `myapi git create-branch <repo> <name>` | Create a branch (`--from <ref>`) |
| `myapi git delete-branch <repo> <branch>` | Delete a branch |
| `myapi git tag <repo> <name>` | Create a tag (`--ref <ref>`) |
| `myapi git merge <repo>` | Fast-forward merge (`--target`, `--source`) |
| `myapi git repack <repo>` | Compact the repository's packfiles |
<!-- generated:end -->

## Examples
<!-- llm:start -->
```bash
# Create a repo and inspect it
myapi git create my-app --default-branch main
myapi git list
myapi git refs my-app

# Commit a generated project — point --dir at the directory (preferred)
myapi git commit my-app --branch main --message "init" --dir ./dist

# Commit one local file (--as places/renames it in the repo)
myapi git commit my-app --branch main --message "add page" \
  --file ./out.html --as index.html

# Or hand-author edits as JSON (deletes, modes, base64 content)
myapi git commit my-app --branch main --message "rm" \
  --changes '[{"path":"old.txt","delete":true}]'
# Each entry: {path, content | content_base64 | delete:true, mode?}
# mode: "100644" (default), "100755" (exec), "120000" (symlink)

# Guard against a stale write (optimistic concurrency)
myapi git commit my-app --branch main --message "fix" \
  --base <expected-tip-sha> \
  --changes '[{"path":"app.js","content":"..."}]'

# Read history & content (no clone)
myapi git log my-app --ref main --limit 20
myapi git show my-app <sha>
myapi git tree my-app main --path src
myapi git blob my-app main README.md        # prints file content
myapi git diff my-app --base main --head feature

# Branches, tags, merge
myapi git create-branch my-app feature --from main
myapi git tag my-app v1.0.0 --ref main
myapi git merge my-app --target main --source feature   # fast-forward only
myapi git delete-branch my-app feature
```

### Clone & push with real git
Hosted repos speak the real git smart-HTTP protocol. Clone, fetch, and push
over HTTPS with **HTTP Basic auth — your MyAPI API key is the password**, any
username works (git accepts the key in either field).

```bash
# URL: https://git.mygitapi.com/<org-slug>/<repo>.git
#   <org-slug> = your org's preview subdomain (myapi org get)
#   <repo>     = repository name (.git suffix optional)

# Clone (key as password; "x" is a throwaway username)
git clone https://x:[email protected]/my-org-slug/my-app.git

# Or set the remote and let git prompt for the password (paste the key)
git remote add origin https://git.mygitapi.com/my-org-slug/my-app.git
git push origin main
```

Capability rules: clone/fetch needs **git read**, push needs **git write**.
An org-locked key only reaches its own org. Unknown slug/repo → 404 (the
surface never leaks which repos exist).
<!-- llm:end -->

## Notes

- **Clone-free is the default mode.** The CLI never needs a working copy — `commit` sends local files (`--dir`/`--file`) or JSON edits (`--changes`), reads come back over the API. Use real git only when you want a local checkout.
- **`merge` is fast-forward only.** No merge commits; the target must be an ancestor of the source. Rebase/merge locally and push instead for non-FF cases.
- **`commit --base`** is the concurrency guard: pass the expected tip SHA to reject a stale write, or `--base ""` to require the branch be newly created. Omit it to create-or-update.
- **Metering.** A `git push` (and `myapi git commit`) is metered like a commit. Clone/fetch (`upload-pack`) is free.
- **Limits.** A push body is capped at 100 MiB; per-repo size limits apply (a push past the cap is reported as a receive-pack failure).
- **Auth field.** git may put the key in the username or password slot — both work. Embedding it in the URL (`https://x:$KEY@…`) avoids the interactive prompt but writes the key into `.git/config`; use a credential helper for anything persistent.

Run `myapi git --help` for the full flag reference.

More from myapihq/myapi