In Oak the branch is the unit of work, not the commit. A branch is one task β usually one agent session or one change a person wants reviewed β and it ends by being squash-merged onto main or closed.
How branches work#
mainexists only on the server. There's no localmainto commit to, and the server refuses pushes to it. It only changes when a branch is merged.- Every other branch is parented onto
main. New branches start from the latestmainyou've fetched, andoak pullkeeps them current by mergingmainin. - You always have a branch.
oak initandoak clonecreate a personal one named<you>-<6 hex chars>(for examplezdgeier-3f2a8b), so two clones of the same repo never collide on push. Your username comes from your login, orOAK_AUTHOR,USER, orUSERNAME. - Branches are cheap. Make one per task. The open-branch view on oak.space and
oak branch triageexist precisely because a repo worked on by agents has a lot of them.
Create and switch#
oak switch -c # new branch off the latest main, generated name
oak switch -c fix-login-redirect # β¦with a name
oak switch -c --clean # β¦and drop uncommitted changes instead of carrying them over
oak switch fix-login-redirect # switch to an existing branch (fetched from the server if needed)
oak switch # pick from a list
oak switch -d 3f9fab02 # detach HEAD at a commit (same as `oak checkout 3f9fab02`)
Uncommitted edits come with you when you create a branch, the way git checkout -b works; pass --clean to start fresh instead. oak switch main is an error β there's no local main to switch to.
Inside a mount, oak switch is refused: a mount is one branch. Mount another branch with oak mount <org>/<repo> --branch <name> instead.
Descriptions#
Commits carry no message. The branch description says what the whole branch does, and it becomes the commit message of the squash commit on main when the branch merges.
oak desc "Retry flaky uploads with jittered backoff"
oak desc --file description.md # from a file
git log -1 --format=%B | oak desc --file - # β¦or from stdin
oak desc --append "Also fixes #212." # add a paragraph to the existing description
oak desc saves locally and, if the branch has been pushed, updates the server too; otherwise the next oak push carries it. It can be changed any number of times until the branch merges.
Write it for someone reading main's history months from now: what changed and why, not a list of touched files. A first line that works as a title, then a blank line and detail, renders best. If a branch merges without a description, the squash commit's message falls back to the branch name.
--append refuses, rather than overwrite, when your local copy of the description is out of date with the server's β it tells you the exact command to refresh with. That makes it safe for several agents to add notes to one branch.
List and inspect#
oak branch # local branches
oak branch --show-current # just the current branch's name
oak branch list --remote # every branch on the server
oak branch list --remote --status open
oak branch show fix-login-redirect --remote
oak info # repo, branch, parent, remote, and linked-repo details
Add --json to any of them for machine-readable output. To compare or review branches without switching to them, see Reviewing branches.
Close and reopen#
oak close # close the current branch
oak close old-experiment --remote --json # close a pushed branch without switching to it
oak close old-experiment --reason "superseded by fix-login-redirect"
Merging closes a branch automatically. Close the ones you're abandoning so they drop off the open-branch view. Closing is idempotent and keeps everything β a closed branch can be reopened from its page on oak.space (or via the API).
Reshape a branch with oak split#
oak split is Oak's git rebase -i. It opens a todo list of the branch's commits where you can reorder them, drop some, or send groups of them to new, independent branches β useful when an agent did two unrelated things on one branch.
oak split # interactive, on the current branch
oak split --from big-branch # on another branch
oak split --plan plan.txt # apply a plan non-interactively (or --plan - for stdin)
oak split --dry-run # print the resulting structure without writing
oak histedit is an alias.
Branch names#
Names can't contain whitespace, control characters, / or \, and main is reserved. Mounts and agent spaces generate names from the task directory plus a short id, like fix-auth-redirect--a1b2c3d4.
oak branch rename exists but is temporarily disabled (the server returns 503) while a storage-integrity issue is fixed. To rename, create a new branch from the old one's work and close the old one.
Limits#
A repo can hold up to 10,000 branches, open and closed. There's no cap on open branches during the beta β see Plans and limits.