Branches
Overview
A branch is a named pointer to a commit, and in Gitmoap it lives in git exactly as it does on your laptop — there is no separate copy of it in a database to fall out of step. You create branches to work on something without disturbing the default branch, open a merge request from one when the work is ready, and delete it once the work has landed.
Everything on this page also works from git itself. The API and the CLI exist for the times when you want to do it without a clone: a script that opens a branch per ticket, a bot that reaps merged branches, a dashboard that lists what is in flight.
Quick start
Start a branch
Create the branch and switch to it:
git switch -c my-change
Push it and track it. It appears under Branches as soon as the push lands, with how far it is ahead of the default branch.
git push -u origin my-change
Before you start
- A repository you can read.Listing and reading branches follows the repository's visibility: a public repository answers anyone, an internal one answers anyone signed in, and a private one answers only its members.
- Developer access to create a branch, and Developer access to delete one.The same level covers both. What actually raises the bar on a particular branch is a branch rule: a protected pattern can require Maintainer to push to it, and the default branch cannot be deleted at all.
- A token with the right scope, if you are calling the API or the CLI rather than clicking:
branch:readto list and read,branch:createto create,branch:deleteto delete. A personal access token carries the scopes you choose when you mint it, so a script that only reads should be given onlybranch:read. - Something to branch from.A new branch starts at a commit that already exists — usually the tip of the default branch.
How to
List the branches in a repository
Each branch comes back with its head commit and how far it is ahead of and behind the default branch, which is the pair of numbers that tells you whether it needs a rebase before it will merge cleanly.
Each also says whether a branch rule protects it, whether you can push to it — with the reason when you cannot, in the same words a push would be refused with — and the open merge requests proposing it. That is what lets an editor offer to commit to a branch only when it would work.
Open the repository and choose Branches in the side navigation. The list shows every branch with its head commit, who pushed it and when, and how far ahead of and behind the default branch it is. Type in the filter box to narrow the list by name; the default branch is pinned to the top and labelled.
gitmoap branches list --repo-id <id>curl -X GET https://api.gitmoap.example/repositories/{repo_id}/branches \ -H "Authorization: Bearer $GITMOAP_TOKEN"Create a branch
A branch is created from another branch, which you always name — there is no default. Give the new branch's name and the branch it starts from; the new branch points at whatever that one points at right now.
Open the repository, choose Branches, then New branch. Give the branch a name and pick the branch it starts from — the default branch is preselected. Create branch takes you to the new branch's view.
gitmoap branches create \ --repo-id <id> \ --branch-name <branch name> \ --from-branch <from branch>curl -X POST https://api.gitmoap.example/repositories/{repo_id}/branches \ -H "Authorization: Bearer $GITMOAP_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "branch_name": "<string>", "from_branch": "<string>" }'The name has to be a valid git ref — no spaces, no .., no leading or trailing / — and it has to be free. Creating a branch over a name that is taken is refused rather than performed, so you cannot move somebody else's branch by accident. Names like feature/login are ordinary: the / is part of the name, not a directory.
Delete a branch
Warning
Deleting a branch is immediate and cannot be undone through Gitmoap. The commits it pointed at are not deleted straight away, but nothing names them any more, so unless you or somebody else has the commit id written down the work is effectively gone. If the branch has been merged, its commits are reachable from the branch it was merged into and nothing is lost.
Two deletions are refused rather than performed, and both refusals are deliberate:
- The default branch cannot be deleted. Every repository's default branch is
main, fixed when the repository is created, and there is no setting that moves it — so this refusal is permanent rather than something to work around. - A branch that an open merge request is merging into cannot be deleted, because the merge request would have nowhere to land. Close or retarget the merge request first.
Deleting a branch that an open merge request is merging from is allowed. The merge request stays, and reports that its source branch is gone — which is what you want when you delete a branch by accident and need to see which work you interrupted.
Open the repository and choose Branches. Find the branch in the list and choose the bin icon at the end of its row. The confirmation names the branch and its head commit; Delete is immediate.
gitmoap branches delete --repo-id <id> --branch-name <id>curl -X DELETE https://api.gitmoap.example/repositories/{repo_id}/branches/{branch_name} \ -H "Authorization: Bearer $GITMOAP_TOKEN"Reference
4 endpoints
GET/repositories/{repo_id}/branchesbranch:read
List branches in a repository
Token scope
branch:read
Send
Path
- repo_iduuidRepository ID
Query
- limitint32optionalPage size (1-100)
- next_tokenstringoptionalPagination cursor
Refuses
400An unreadable pagination token, or a malformed repository ID401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Not found — or found and private, which is masked as absent
Receive
items[]object20 fields
- aheadint32
- behindint32
- branch_namestring
commitobject13 fields
- author_avatar_urlobjectoptional
- author_emailstring
- author_namestring
- authored_atstring
- commit_shastring
- committed_atstring
- committer_avatar_urlobjectoptional
- committer_emailstring
- committer_namestring
- messageobjectoptional
- repository_iduuid
- short_shastring
- titlestring
- protectedbooleanA branch rule protects this branch.
- push_refusalobjectoptionalWhy the caller may not push here, in a sentence to show them. Absent when they may.
- repository_iduuid
- viewer_can_pushbooleanWhether the caller may push to this branch — the same verdict a
git pushor a commit written in the browser gets.falsefor someone not signed in.
- next_tokenobjectoptional
GET/repositories/{repo_id}/branches/{branch_name}branch:read
Get a branch by name
Token scope
branch:read
Send
Path
- repo_iduuidRepository ID
- branch_namestringBranch name
Refuses
400Bad request — a path parameter is not a well-formed value of its type401Unauthenticated — no credential, or an invalid one403Forbidden — the caller's access level or token scope is insufficient404Branch not found
Receive
- aheadint32
- behindint32
- branch_namestring
commitobject13 fields
- author_avatar_urlobjectoptional
- author_emailstring
- author_namestring
- authored_atstring
- commit_shastring
- committed_atstring
- committer_avatar_urlobjectoptional
- committer_emailstring
- committer_namestring
- messageobjectoptional
- repository_iduuid
- short_shastring
- titlestring
open_merge_requests[]object2 fields
- iidint64
- target_branchstring
- protectedbooleanA branch rule protects this branch.
- push_refusalobjectoptionalWhy the caller may not push here, in a sentence to show them. Absent when they may.
- repository_iduuid
- viewer_can_pushbooleanWhether the caller may push to this branch — the same verdict a
git pushor a commit written in the browser gets.falsefor someone not signed in.
POST/repositories/{repo_id}/branchesbranch:create
Create a branch in a repository
Token scope
branch:create
Will count against
branches_per_repo
not enforced today
Send
Path
- repo_iduuidRepository ID
Body
- branch_namestring
- from_branchstring
Refuses
400Invalid request401Unauthenticated — no credential, or an invalid one403The caller may not push here, or a branch rule protects this name404Repository or source branch not found409A branch with this name already exists422The name breaks the repository's branch-name push rule
Receive
The same shape get_branch returns — 9 fields. Go to it
Show it here
- aheadint32
- behindint32
- branch_namestring
commitobject13 fields
- author_avatar_urlobjectoptional
- author_emailstring
- author_namestring
- authored_atstring
- commit_shastring
- committed_atstring
- committer_avatar_urlobjectoptional
- committer_emailstring
- committer_namestring
- messageobjectoptional
- repository_iduuid
- short_shastring
- titlestring
open_merge_requests[]object2 fields
- iidint64
- target_branchstring
- protectedbooleanA branch rule protects this branch.
- push_refusalobjectoptionalWhy the caller may not push here, in a sentence to show them. Absent when they may.
- repository_iduuid
- viewer_can_pushbooleanWhether the caller may push to this branch — the same verdict a
git pushor a commit written in the browser gets.falsefor someone not signed in.
DELETE/repositories/{repo_id}/branches/{branch_name}branch:delete
Delete a branch
Token scope
branch:delete
Send
Path
- repo_iduuidRepository ID
- branch_namestringBranch name
Refuses
400Cannot delete the default branch401Unauthenticated — no credential, or an invalid one403The caller may not delete branches here, or a branch rule protects this branch404Branch not found409The branch is the target of an open merge request
Receive
No body.
Troubleshooting
400 BAD_REQUESTon any call, mentioning repo_id
- Cause
- The repository id in the URL is not a well-formed id — usually a path like
my-group/my-repopasted where an id belongs - What to do
- Use the repository's id, or call the by-path endpoint that takes a path
400 BAD_REQUESTon create, mentioning the name
- Cause
- The name is not a valid git ref — a space, a
.., a leading or trailing/, or a control character - What to do
- Rename it. Letters, digits,
-,_,.and/between segments are all safe
400 BAD_REQUESTon delete, mentioning the default branch
- Cause
- You are deleting the branch the repository defaults to, which is
mainon every repository - What to do
- Nothing deletes it, and no setting moves the default elsewhere. If
mainholds the wrong history, push the history you want onto it and delete the other branch instead
409 CONFLICTon create
- Cause
- A branch with that name already exists
- What to do
- Pick another name, or delete the existing branch first if you meant to replace it. The existing branch is left exactly where it was
403 FORBIDDENon create
- Cause
- You have read access but not Developer, or a branch rule protects the name you chose (
BRANCH_PROTECTED) - What to do
- Ask an Owner or Maintainer of the repository to raise your access level, or pick a name the rule does not cover
403 FORBIDDENon delete, where create works
- Cause
- A branch rule protects the branch you are deleting and sets a push threshold above your level. Creating worked because the branch you created matched no such rule
- What to do
- Check the repository's branch rules for a pattern matching this branch. Ask an Owner or Maintainer to raise your level, to add you to the rule's push allowlist, or to delete the branch for you
403 INSUFFICIENT_SCOPE
- Cause
- Your token is valid but was minted without the scope this call needs
- What to do
- Mint a new token that carries
branch:createorbranch:delete. Scopes are chosen at mint time and cannot be added to a token afterwards
404 NOT_FOUNDon a repository you are sure exists
- Cause
- Either the repository is private and you are not a member, or the branch name is wrong
- What to do
- A private repository answers
404rather than403to anyone who is not a member, so that its existence stays private. Check you are a member, then check the spelling
409 CONFLICTon delete
- Cause
- An open merge request is merging into this branch
- What to do
- Close the merge request, or retarget it at another branch, then delete
The branch is there in git but not in the list
- Cause
- The branch was pushed to a different repository, or the push was rejected by a push rule
- What to do
- Check the push output — a rejected push leaves nothing behind
Related
- Merge requestshow work on a branch gets reviewed and merged
- Branch rulesprotecting a branch so it cannot be force-pushed or deleted
- Push rulesconstraining what may be pushed to a branch in the first place