@@ -0,0 +1,89 @@ |
| 1 | +# Forks |
| 2 | + |
| 3 | +Manage a repo's fork network. Mirrors GitHub's |
| 4 | +`/repos/{owner}/{repo}/forks` shape. |
| 5 | + |
| 6 | +Scopes: `repo:read` on GET, `repo:write` on POST. Policy gates |
| 7 | +are `ActionRepoRead` and `ActionForkCreate`. See |
| 8 | +[common API conventions](overview.md) for envelopes and headers. |
| 9 | + |
| 10 | +## List forks |
| 11 | + |
| 12 | +``` |
| 13 | +GET /api/v1/repos/{owner}/{repo}/forks[?page=&per_page=] |
| 14 | +``` |
| 15 | + |
| 16 | +Paginated, recency-sorted, soft-deleted rows excluded. Per-row |
| 17 | +visibility filter applies — a private fork of a public repo |
| 18 | +only surfaces to viewers who can see the fork. |
| 19 | + |
| 20 | +```json |
| 21 | +[ |
| 22 | + { |
| 23 | + "id": 101, |
| 24 | + "name": "demo", |
| 25 | + "owner_login": "bob", |
| 26 | + "owner_display_name": "Bob", |
| 27 | + "description": "", |
| 28 | + "visibility": "public", |
| 29 | + "star_count": 0, |
| 30 | + "fork_count": 0, |
| 31 | + "init_status": "initialized", |
| 32 | + "created_at": "2026-05-12T15:00:00Z" |
| 33 | + } |
| 34 | +] |
| 35 | +``` |
| 36 | + |
| 37 | +`init_status` is one of `init_pending` / `initialized` / |
| 38 | +`init_failed` — clients can poll the single-repo endpoint to |
| 39 | +watch a fresh fork transition out of `init_pending`. |
| 40 | + |
| 41 | +## Create a fork |
| 42 | + |
| 43 | +```http |
| 44 | +POST /api/v1/repos/alice/demo/forks |
| 45 | +Authorization: Bearer <pat> |
| 46 | +Content-Type: application/json |
| 47 | + |
| 48 | +{ |
| 49 | + "name": "demo-fork", |
| 50 | + "visibility": "private" |
| 51 | +} |
| 52 | +``` |
| 53 | + |
| 54 | +All fields are optional: |
| 55 | + |
| 56 | +- `name` — repo name on the caller's account. Defaults to the |
| 57 | + source repo's name. Forking your own repo into the same name |
| 58 | + is refused (409); pass a different `name`. |
| 59 | +- `visibility` — must be ≤ source visibility. A public source |
| 60 | + can fork to private; a private source is pinned to private. |
| 61 | + |
| 62 | +Targets the **authenticated user's namespace only** today. Org |
| 63 | +targets land in a follow-up. |
| 64 | + |
| 65 | +Returns `201 Created` with the persisted row immediately. The |
| 66 | +on-disk `git clone --bare --shared` runs in the background |
| 67 | +worker (`repo:fork_clone` kind), so the response carries |
| 68 | +`init_status: "init_pending"` and the fork's URL resolves right |
| 69 | +away. |
| 70 | + |
| 71 | +```json |
| 72 | +{ |
| 73 | + "id": 101, |
| 74 | + "name": "demo-fork", |
| 75 | + "owner_login": "bob", |
| 76 | + "visibility": "public", |
| 77 | + "init_status": "init_pending", |
| 78 | + "source_repo_id": 42, |
| 79 | + "default_branch": "trunk", |
| 80 | + "created_at": "2026-05-12T15:00:00Z" |
| 81 | +} |
| 82 | +``` |
| 83 | + |
| 84 | +## Errors |
| 85 | + |
| 86 | +- `404` — source repo not visible. |
| 87 | +- `409` — self-fork with no `name` override, target name |
| 88 | + collides with an existing repo, or source archived. |
| 89 | +- `422` — `visibility` exceeds source visibility. |