Files
lancedb/docs/src/js/classes/Branches.md
T
Drew Gallardo 65cd142c7e feat: add remote branch diff and merge client APIs (#3686)
This PR adds some support for `diff` / `merge` in the remote client as
for local tables we stay `NotSupported` until
https://github.com/lance-format/lance/issues/7263.


This wires the two review-and-land calls against the remote REST API:
- `POST /v1/table/{id}/branches/diff`
- `POST /v1/table/{id}/branches/merge`

Rust gets typed results (`BranchDiff`, `MergeBranchResult`). Python
returns the wire JSON, same shape as the REST response.

Merge here means promoting a branch's added columns onto `main`.

### Behavior
- Remote only. Local raises `NotSupported`.
- A rejected merge is not an exception. HTTP 409 still returns `Ok` / a
dict with `status="rejected"` and blockers in `diff.mergeBlockers`.
- Unknown blocker / status codes parse as `Unknown` so a newer server
does not break older clients.
- `MergePreview` tolerates missing fields for the same reason.
- Merge requests are not retried. 409 is final and carries the body you
need.

### Example
```python

table = db.open_table("images")

table.branches.create("exp")
exp = table.branches.checkout("exp")

exp.add_columns({"tag": "cast('draft' as string)"})

diff = table.branches.diff("exp")
preview = table.branches.merge("exp", dry_run=True)
result = table.branches.merge("exp", dry_run=False)

if result["status"] == "merged":
    print("landed at", result["mainVersionAfter"])
elif result["status"] == "rejected":
    print(result["diff"]["mergeBlockers"])
```

### Testing
cargo test -p lancedb --features remote diff_branch
cargo test -p lancedb --features remote merge_branch

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-18 12:38:05 -07:00

2.2 KiB

@lancedb/lancedbDocs


@lancedb/lancedb / Branches

Class: Branches

Branch manager for a Table.

Unlike tags, create and checkout return a new Table handle scoped to the branch; writes on it do not affect main.

Methods

checkout()

checkout(name, version?): Promise<Table>

Check out an existing branch and return a handle scoped to it.

With version set, the returned handle is pinned to that version of the branch (a read-only, detached view); otherwise it tracks the branch's latest and stays writable.

Parameters

  • name: string

  • version?: number

Returns

Promise<Table>


create()

create(
   name,
   fromRef?,
   fromVersion?): Promise<Table>

Create a branch and return a handle scoped to it.

Parameters

  • name: string Name of the new branch.

  • fromRef?: string Source branch to fork from. Defaults to main.

  • fromVersion?: number A specific version on fromRef. Defaults to latest.

Returns

Promise<Table>


delete()

delete(name): Promise<void>

Delete a branch.

Parameters

  • name: string

Returns

Promise<void>


diff()

diff(fromBranch): Promise<BranchDiff>

Compare a branch against main without modifying either branch.

Parameters

  • fromBranch: string

Returns

Promise<BranchDiff>


list()

list(): Promise<Record<string, BranchContents>>

List all branches, mapping name to branch metadata.

Returns

Promise<Record<string, BranchContents>>


merge()

merge(fromBranch, dryRun): Promise<MergeBranchResult>

Merge a branch into main.

Set dryRun to true to preview the merge. A rejected merge resolves with status: "rejected" instead of throwing.

Parameters

  • fromBranch: string Branch to merge from.

  • dryRun: boolean = false When true, only preview the merge. Defaults to false.

Returns

Promise<MergeBranchResult>