Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.oxen.ai/llms.txt

Use this file to discover all available pages before exploring further.

A workspace is like a working directory that lives on the Oxen server. You can add, rm, and modify files in a workspace and then commit those changes in bulk, without ever cloning the repository to your local machine. Under the hood, every workspace is pinned to a specific commit on a branch. All staged changes are computed relative to that commit. Staged changes survive server restarts, but they are not part of the repository’s commit history until you commit the workspace, so they can be deleted without leaving a trace.

Why use a workspace?

Reach for a workspace when you want to:
  • Edit a repository that’s too large to clone. Stage changes to a 100GB+ repo without copying it to your machine.
  • Bulk-import data without keeping a local copy. oxen workspace add uploads directly to the server, so you don’t pay the disk cost of writing every file into a local .oxen store first.
  • Batch many changes into a single commit. Add, remove, and modify dozens of files server-side, then land them as one atomic commit.
  • Let multiple clients contribute to one staged commit. A named workspace can be written to by several processes or users before anyone commits β€” useful for workflows like labeling UIs, ingestion services, or agents producing training data.
  • Keep a long-lived staging area across multiple commits. Named workspaces persist after commit and fast-forward to the new commit, so the same workspace can be reused over and over.
If you’re working in a repo small enough to clone and just want the normal add β†’ commit β†’ push flow, you don’t need a workspace β€” see the Version Control guide instead.

Quick start

Add to an existing repo without cloning it

Imagine a repository with 1 million images. Instead of cloning the data, init an empty local repo, point it at the remote, and write directly to a workspace.
oxen init
oxen config --set-remote origin https://hub.oxen.ai/ox/ImageNet-1k
oxen workspace create --name add_image --branch main
# Stage a single file into the images/ directory of the workspace
oxen workspace add /path/to/my_images/image.jpg --directory images/ --workspace-name add_image
# See what's staged
oxen workspace status --workspace-name add_image
# Commit the staged changes to main
oxen workspace commit -m "Add new image to images/ directory" -n add_image -b main

Bulk-import data into a fresh repo

oxen workspace add never writes data to your local machine β€” files stream directly to the remote. This avoids the disk and time cost of add β†’ commit β†’ push, which would otherwise copy every file into a local .oxen store first.
oxen init
oxen config --create-remote --host hub.oxen.ai --scheme https --name ox/ImageNet-1k
oxen workspace create  # Create a workspace to import the data. This will return a workspace ID
oxen workspace add images/ --workspace-id [WORKSPACE_ID]
oxen workspace commit -m "Import 1 million images" -w [WORKSPACE_ID]
Workspaces can also be driven through the HTTP API β€” useful when you’re building a custom client (labeling UI, ingestion daemon, agent, etc.) that needs to write to a repo without shipping the Oxen CLI or Python SDK.

How it works

Every workspace references a specific commit, the same way a branch does. All your staged operations are recorded as a diff against that base commit. When you commit a workspace:
  1. Oxen applies your staged diff on top of the workspace’s base commit to produce a new commit.
  2. That new commit is added to a target branch on the remote (see Committing changes for how the target is chosen).
  3. If the target branch has advanced past the workspace’s base commit, Oxen attempts to merge. Conflicts cause the commit to fail and you’ll need to resolve them before retrying.
Because workspaces are commit-scoped, two workspaces created from the same branch at different times can see completely different views of the repo. That’s intentional β€” it gives you isolation while staging β€” but it also means a long-lived workspace can drift from the branch tip and accumulate conflicts.

Creating a workspace

A workspace is created against a remote repository, and optionally against a specific branch.
from oxen import RemoteRepo
from oxen import Workspace

repo = RemoteRepo("ox/CatDogBBox")
workspace = Workspace(repo, "add-images")
If no branch is provided, the default branch (usually main) is used.
from oxen import RemoteRepo
from oxen import Workspace

repo = RemoteRepo("ox/CatDogBBox")
workspace = Workspace(repo)
The workspace is pinned to whatever commit the branch points at when you create it. You can only create workspaces from branches that already exist on the remote.

Named vs. unnamed workspaces

Every workspace has an auto-generated id. You can optionally also give it a human-readable name.
from oxen import RemoteRepo
from oxen import Workspace

repo = RemoteRepo("ox/CatDogBBox")
workspace = Workspace(repo, name="my-workspace-name")
The name matters because of two behavioral differences:
Unnamed workspaceNamed workspace
Lifetime after commitDeletedPersists, fast-forwarded to the new commit
Best forOne-shot imports, throwaway stagingLong-lived staging, multi-commit or multi-client workflows
Use a named workspace when you expect to make multiple commits from the same workspace, or when several processes/users will share it. Use an unnamed workspace for one-off imports where you don’t need it to stick around.

Identifying a workspace in CLI commands

Most workspace commands need to know which workspace you’re targeting. You can reference a workspace by either its id or its name:
  • --workspace-id <id> (short: -w) β€” reference by the auto-generated id returned from oxen workspace create.
  • --workspace-name <name> (short: -n) β€” reference by the name you set with --name at create time.

Listing workspaces

List the workspaces on a remote with oxen workspace list.
oxen workspace list -r my_remote  # Defaults to `origin` if no remote is provided

Adding files

oxen workspace add streams a file’s contents directly to the server and stages it on the workspace.
from oxen import RemoteRepo
from oxen import Workspace

repo = RemoteRepo("ox/CatDogBBox")
workspace = Workspace(repo, "add-images")
workspace.add("/path/to/image.png")
status = workspace.status()
print(status.added_files())

Unstaging a file

To remove a file you’ve staged on the workspace (without touching the base repo), unstage it with oxen workspace rm --staged.
CLI
oxen workspace rm --staged image.jpg -w my-workspace-id

Deleting a file from the base repo

oxen workspace rm without --staged stages a deletion of a file that exists in the base repo. When you commit the workspace, that file will be removed from the branch. Use --staged if you only want to unstage a previously added file.
oxen workspace rm image.jpg -w my-workspace-id

Committing changes

Commit a workspace to land its staged changes as a new commit on the remote.
from oxen import RemoteRepo
from oxen import Workspace

repo = RemoteRepo("ox/CatDogBBox")
workspace = Workspace(repo, "add_images")
workspace.commit("adding an image using a workspace", "add_images")
If you don’t provide a target branch, the commit will be made to a new branch on the remote.
from oxen import RemoteRepo
from oxen import Workspace

repo = RemoteRepo("ox/CatDogBBox")
workspace = Workspace(repo, "my_branch")
workspace.commit("adding an image using a workspace")  # No branch is provided, so this will create a new branch
After a successful commit:
  • An unnamed workspace is deleted.
  • A named workspace is fast-forwarded to point at the new commit, so you can keep using it.
If merge conflicts are detected (because the target branch has advanced past the workspace’s base commit), the commit will fail.