A data branch is a named view of a dataset where writes land without touching the trunk, main. A build run on a branch writes its outputs there, so a change can be tested end to end on real data and only then promoted. Branches are a capability of tabular (Iceberg) datasets: a branch is a copy-on-write ref over the same files, forked in O(1), promoted by moving the trunk to the branch’s snapshot. A file dataset has one version. A write naming another branch is a 400; a read takes no notice of the branch and answers the one version there is. A build on a branch whose output is a file dataset is refused before it starts, for the same reason: it could only have written the trunk under another name. Branch names: a letter or digit, then letters, digits, ., _ or -, up to 100 characters. A branch is created by its first write.

From the library

Every file call and empty take branch=:
In SQL, suffix the handle with the branch:
An unknown branch on a tabular dataset is a 400, never a silent fall back to the trunk.

In a build

Inside a build the library carries the build’s branch for you: the inputs are read on it when they have it and on the trunk otherwise, and the output is written on it. Nothing in the transform’s code names a branch. A file dataset among the inputs is read as it is, since it has one version. The platform also couples the data branch to the code: a build on data branch experiment-q3 checks out the git branch experiment-q3 when the repository has one, and the configured branch otherwise. The match is by name, so prefer specific names over dev.

Lifecycle

Forking a branch across a whole lineage, merging it back, promoting one dataset’s branch or deleting a branch are done from the Atlas interface or the orchestration API. A fork across a lineage branches its tabular datasets and skips the others. GET /datasets/{id}/branches lists a dataset’s branches; a file or vector dataset lists main.
Vector datasets have no branches either: branch= other than main is a 400 on them.