--- topic: branches source_keys: - gitea-mcp-repo - gitea-mcp-slim-go --- # Branch operations Call signatures below were verified live against the deployed `gitea-mcp` server via `ToolSearch`, not copied from research docs — this is deliberate: research docs are generated from source code at a point in time and can drift from the server actually deployed. **Last verified against gitea-mcp v1.7.0**, as reported by `get_gitea_mcp_server_version`. Re-verify against the live schema if the deployed version differs or these tools behave differently than documented here. ## `list_branches` **Parameters:** - `owner` (string, required) - `repo` (string, required) - `page` (number, optional, default: `1`) - `per_page` (number, optional, default: `30`) **Call:** ```text list_branches owner: repo: ``` **Response:** one object per branch: `name`, `protected` (bool), `commit_sha` (present when the underlying commit data is available). Paginate for the full list (see Gotchas) — iterate `page` until the count is less than `per_page`. ## `create_branch` **Parameters:** - `owner` (string, required) - `repo` (string, required) - `branch` (string, required) — new branch name - `old_branch` (string, optional) — source branch; if omitted, defaults to the repo's default branch server-side (not necessarily your current local checkout) **Call:** ```text create_branch owner: repo: branch: old_branch: ``` Default dispatch: if the user gives a base ("branch off of X", "from X"), pass it as `old_branch`. If they don't specify a base and you're mid-task on a local branch, pass your current branch (`rtk git branch --show-current`) as `old_branch` so the new branch forks from where you're actually working, rather than silently falling back to the repo default. If neither applies (e.g. a fresh top-level request with no working branch context), omit `old_branch` and let it default server-side. A branch name collision returns `409 Conflict`. ## `rename_branch` **Parameters:** - `owner` (string, required) - `repo` (string, required) - `branch` (string, required) — the branch's current name - `new_name` (string, required) — the name to move it to **Call:** ```text rename_branch owner: repo: branch: new_name: ``` A rename moves the ref server-side; it is not a delete-plus-create, and no commit history is rewritten. What it does to things *pointing at* the old name — open pull requests using it as head or base, a branch protection rule matching it, CI config, and tracking branches on every other clone — is **not confirmed** by this skill's sources: the deployed tool describes itself only as "Rename an existing branch in a repository". Treat a rename of a branch with open PRs or a protection rule as a change needing verification afterward (`list_branches`, plus `gitea-prs` for the PR side), and confirm with the user first, exactly as for `delete_branch` below. A collision with an existing branch name is expected to return `409 Conflict` by analogy with `create_branch`, not separately confirmed. ## `delete_branch` **Parameters:** - `owner` (string, required) - `repo` (string, required) - `branch` (string, required) **Call:** ```text delete_branch owner: repo: branch: ``` Before calling this, see the `delete_branch` Gotcha in SKILL.md. If the target branch's name isn't obviously a scratch/feature branch, call `list_branches` first and check `protected` on the matching entry — name-matching `main`/`master` alone isn't authoritative, since a repo can protect a differently-named default branch. Confirm explicitly with the user before deleting anything protected, every time, regardless of how the request is phrased. ## Token scope `list_branches`, `create_branch` and `delete_branch` all require `write:repository`. Gitea gates reads behind write scope for repo-scoped operations, so `list_branches` needs the same scope as the write operations, not `write:issue` alone. An earlier version of this doc claimed `write:issue` alone was sufficient for `list_branches`, based on empirical testing under a token that held both `write:issue` and `write:repository` simultaneously — that test didn't isolate the variable, so it couldn't actually establish `write:issue` alone as sufficient. `rename_branch` is a write on the same repo-scoped surface and is inferred to need `write:repository` too — inferred by analogy, not separately confirmed.