Develop without GitHub
A repository that already lives on this host can be a project. sbxm does not clone it. The repository itself acts as the origin, and the sandbox is a disposable place to work in that you can recreate from the host. Pass the repository’s Git directory, not its working tree.
cd ~/Projectssbxm add --local ~/code/<repository>/.gitsbxm open local/<repository>Registering
Section titled “Registering”The Remote SSH integration of Docker Sandboxes must be set up on this host, since the host repository reaches the sandbox over SSH; sbxm status --global shows whether it is, and open and rebuild check it before they build anything.
The path must be a Git directory: the .git of a working tree, a bare repository, or the .git file of a worktree created with git worktree add or of a submodule. A working-tree directory is refused, because a directory can hold more than one repository and does not say which one it means; Git does not search upward from the path either. A symlink or a .git file is resolved, and the real path of the repository is recorded. For a worktree, that is the repository its worktrees share, so every worktree of one repository adds the same project.
Like any project, the project directory is created in the directory you run add from, so run it from outside the repository; add refuses to create it inside any working tree of the repository or inside its Git directory. The project ID is local/<name>, where the name is the directory name git clone would use — <repository> for ~/code/<repository>/.git, app for app.git — unless you pass --name <name>. When that name cannot name a project, add asks for --name.
The sandbox starts from the branch the Git directory you passed is on; for a worktree’s .git, that is the branch of that worktree. When it is detached, pass the starting branch with --detach. No GitHub token is involved, so there is nothing to register before open.
Syncing with the host
Section titled “Syncing with the host”Run sbxm sync to sync the host repository and the sandbox. The host repository plays the part GitHub plays for a GitHub project: the sandbox’s branches and tags reach it the way git push would take them, and its branches and tags reach the sandbox’s origin the way git fetch --prune would bring them. Git refuses what it would refuse in a push, such as a branch that is not a fast-forward or a tag that already points elsewhere, and the refused commits stay under refs/sbx/<sandbox>/. The branch checked out on the host moves with its files when git merge --ff-only would go through in its worktree; uncommitted changes that overlap stop it, and their files are named. The sandbox’s worktrees and branches are left alone, and sync names the sandbox branches that lack commits the host has. Take them in onto origin/<branch> inside the sandbox; a branch that diverged from the host needs a merge or rebase and another sync, as you would before pushing to GitHub again.
Getting the host’s history into the sandbox
Section titled “Getting the host’s history into the sandbox”When open builds the sandbox, the host repository pushes its branches into the sandbox’s origin/* and its tags to the same names, over ssh <sandbox>.sbx, the same connection that open uses. The managed worktrees are then created from origin/<branch> as they are for a GitHub project. The connection starts from the host, never prompts, and never forwards the host’s SSH agent; nothing in the sandbox can reach the host repository. The sandbox’s origin is set to sbxm-host::<project-id>, so git fetch origin or git push origin inside the sandbox fails without changing anything; run sbxm sync on the host instead.
sbxm apply --worktrees sends the host repository again before it adds worktrees, as sbxm sync does, so the new worktrees start from the host’s current branches.
Automatic save
Section titled “Automatic save”Only work committed since the last save can be lost, so sbxm narrows that window by saving the sandbox’s commits on its own into refs/sbx/<sandbox>/ of the host repository. An automatic save never moves your branches or tags; only sbxm sync does, by Git’s rules. It saves:
- before
stopstops a running sandbox, - before
rebuildanddestroycheck what would be lost, includingdestroy --force, - every 10 minutes while an
opensession is connected, silently, since the terminal belongs to SSH, - after the session closes, with the project lock taken again.
A stopped sandbox is never started just for this. When something was saved, a line says so on stderr. When the save fails, the command still goes on, and a warning says that anything committed since the last save is only in the sandbox, with the sbxm sync command to retry. Uncommitted changes are not saved; commit them first.
What rebuild and destroy protect
Section titled “What rebuild and destroy protect”The sandbox’s origin is only a copy of the host repository, and it disappears with the sandbox. So for a project added with --local, rebuild and destroy count a commit as kept only when the host repository reaches it: from one of its branches or tags, or from what was saved under refs/sbx/<sandbox>/. A commit the host does not have stops them. An interactive terminal offers to save it and continue.
Uncommitted changes stop them the same way as for a GitHub project. Commit them in the sandbox first.
Rebuilding and recovering
Section titled “Rebuilding and recovering”sbxm rebuild recreates the sandbox from the host repository. The same restoring happens whenever open or repair builds the sandbox again for a project that was built before, for example after the sandbox was removed outside sbxm. The first build of a newly added project restores nothing, even when a project of the same name added earlier left saved branches on the host. After the new sandbox has read its origin, the host repository pushes the branches saved under refs/sbx/<sandbox>/heads/ into it as sandbox branches of the same names, over the same SSH connection that open uses. A restored branch tracks origin/<branch> when the host has a branch of that name. The worktree on the start branch is then recreated at the saved tip, so work continues where it was saved. Detached worktrees start from origin/<branch> as usual; the heads they had are still on the host under refs/sbx/<sandbox>/worktrees/. The result lists the branches that came back. A sandbox repository that already has branches is taken over as it is, and nothing is restored into it; one that stopped before any branch came back gets them on the next open or repair.