## lamindb.Branch

| class lamindb.Branch(name: str, description: str | None = None) |
class lamindb.Branch(*db_args)

 Bases: "BaseSQLRecord"

 Branches for change management with archive and trash states.

 Every "SQLRecord" object lives on a branch that determines its life
 cycle and visibility in queries and searches.

 -[ The 3 built-in branches: "main", "trash" & "archive" ]-

 The "main" branch acts as the default branch.

 The "trash" branch acts like a trash bin on a file system. It you
 delete a "SQLRecord" object via ".delete()", it gets moved onto the
 "trash" branch and scheduled for deletion.

 The "archive" acts like an archive that hides objects from queries
 and searches without scheduling them for deletion. To move an
 object into the archive, run: "obj.branch_id = 0; obj.save()".

 Guide: Manage changes.

 Parameters:
 * **name** -- A unique name. When lower-cased, is constrained to
 be unique across all branches.

 * **description** -- A description.

# Examples

 To create a contribution branch and switch to it, run:

 lamin switch -c my_branch

 To merge a contribution branch into "main", run:

 lamin switch main  # switch to the main branch
 lamin merge my_branch  # merge contribution branch into main

 To see the current branch along with other information, run:

 lamin info

 To annotate the current branch with a "README.md", run:

 lamin annotate branch --readme README.md

 To comment on the current branch, run:

 lamin annotate branch --comment "I think we should revisit this, tomorrow, WDYT?"

 To describe the current branch (optionally include comments), run:

 lamin describe branch --include comments

 To trace on which branch a "SQLRecord" object was created, run:

 sqlrecord.created_on.describe()

 To open a Change Request for a branch, run:

 -[ CLI ]-

 lamin update branch --status draft  # for current branch
 lamin update branch --name my_branch --status review  # for any branch

 -[ Python ]-

 branch = ln.Branch.get(name="my_branch")
 branch.status = "draft"
 branch.save()

 branch.status = "review"
 branch.save()

 Just like Pull Requests on GitHub, branches are never deleted so
 that the provenance of a change stays traceable.

# Notes

 -[ Managing "is_latest" during branching ]-

 "is_latest" is branch-aware during development and reconciled on
 merge.

 * Creating a new version on a contribution branch keeps the
 previous version on "main" as "is_latest=True".

 * After "lamin merge", only one object per version family remains
 with "is_latest=True" in the target branch.

 * If both source and target branches have "is_latest=True", the
 merged branch keeps the newest object by "created_at".

 Example flow:

 # before merge
 # main: v1.is_latest=True
 # contribution branch: v2(revises=v1).is_latest=True
 lamin switch main
 lamin merge my_branch
 # after merge on main: v2.is_latest=True, v1.is_latest=False

 -[ Logical vs. physical branching ]-

 LaminDB uses **logical branching** via "SQLRecord"'s ".branch"
 field, treating "branch" like any other field during queries &
 tracing, and keeping infrastructure simple and platform-agnostic.
 However, it doesn't allow isolating SQL "UPDATE" statements on a
 branch (only their corresponding "DbWrite" events). Here are some
 notable alternatives:

 * Some Postgres platforms like Supabase or Neon, by contrast,
 provide physical branching through cloning entire databases. This
 allows for isolated SQL "UPDATE" statements but creates separate,
 disconnected environments and much overhead.

 * Project Nessie is a versioned catalog for data lakes that tracks
 file states. LaminDB is analogous to Nessie in that it also
 treats branching on the metadata catalog level (considering
 LaminDB's SQL database as the metadata catalog).

 * Dolt is a specialized database engine that provides storage-level
 branching. It allows branch isolation and merging at the engine
 level. While powerful, it requires using the Dolt database
 itself.

 Why logical branching? Data science and ML workflows are primarily
 append-only. Because a "change" usually results in a new version of
 an artifact, transform, or collection or new runs or other new
 objects rather than an in-place modification, the row-level
 "branch" field provides isolation for 99% of use cases. This avoids
 the technical complexity of row duplication, preserves database
 integrity, and allows the "is_latest" logic to reconcile versions
 globally upon merge.

 property status: Literal['standalone', 'draft', 'review', 'merged', 'closed']

 Branch status.

 Get and set the status of the branch.

| --- | --- | --- |
| status | code | description |
| =============== | ======= | ==================================================== |
| "closed" | -2 | Change Request was closed without merging. |
| --- | --- | --- |
| "merged" | -1 | The branch was merged into another branch. |
| --- | --- | --- |
| "standalone" | 0 | A standalone branch without Change Request. |
| --- | --- | --- |
| "draft" | 1 | Change Request exists but is not ready for review. |
| --- | --- | --- |
| "review" | 2 | Change Request is ready for review. |
| --- | --- | --- |

 The database stores the branch status as an integer code in
 field "_status_code".

 -[ Example ]-

 See the status of a branch:

 branch.status
 #> 'standalone'

 Open a Change Request in draft state:

 branch.status = "draft"
 branch.save()

 Request review for the Change Request:

 branch.status = "review"
 branch.save()

 Query by status:

 ln.Branch.filter(status="merged").to_dataframe()

 name: "str"

 Name of branch.

 uid: "str"

 Universal id.

 This id is useful if one wants to apply the same patch to many
 database instances.

| description: "str" | "None" |

 Description of branch.

 created_at: "datetime"

 Time of creation of record.

 space: Space

 The space in which the object is defined.

 created_by: User

 Creator of branch.

 users: RelatedManager[User]

 Users linked to this branch (e.g. reviewers) ← "branches".

 ulabels: RelatedManager[ULabel]

 ULabels annotating this branch ← "ulabel".

 projects: RelatedManager[Project]

 Projects annotating this branch ← "project".

 ablocks: RelatedManager[BranchBlock]

 Attached blocks ← "branch".