oak mount puts a working tree on top of a remote repository without cloning it. Files are fetched the first time something reads them, so you can be editing a multi-gigabyte monorepo within seconds, and running ten tasks in parallel costs ten mounts, not ten clones.
oak mount acme/monorepo # mounts at ./monorepo
oak mount acme/monorepo ./fix-auth # β¦or wherever you say
cd fix-auth
$EDITOR src/auth/callback.rs # only the files you touch are downloaded
oak status && oak commit && oak push
Each mount runs as a background daemon; the command returns as soon as the mount is live. Before your first mount, do the one-time setup for your OS.
How a mount works#
- A mount is one branch. By default
oak mountstarts a fresh virtual branch off the latestmain, named after the mount directory plus a short id β mount at./fix-authand you're onfix-auth--a1b2c3d4. - Edits stay local until you push. Changes go into an overlay on your machine β the active commit, the one you're amending as you edit.
oak commitcheckpoints it onto the virtual branch and starts a new one;oak pushpublishes the branch like any other. - The normal commands just work. Inside a mount,
oak status,diff,commit,desc,log,hash,info,push,pull,finish,conflict, andagent stateall operate on the mount's virtual branch, so a mount feels like a clone.
A few things are different inside a mount:
| Command | Inside a mount |
|---|---|
oak switch | Refused β a mount is one branch. Mount another branch elsewhere. |
oak merge | Doesn't run. Merge from a clone or the web. |
oak reset, oak restore | Don't run. Use oak diff / oak status to see the overlay, or end the mount with --force to discard it. |
| Hooks | Don't run. |
oak commit --json, --push | Not supported; run oak commit then oak push. |
Continue an existing branch#
oak mount acme/monorepo ./fix-auth --branch fix-auth--a1b2c3d4
--branch mounts an existing remote branch instead of starting a fresh one: its history and files become the mount's. Use it to pick up a branch an agent already pushed, give it a follow-up, or resolve its conflicts without a full clone.
Finish, end, and list mounts#
oak mount list # every mount, labelled live, stale, or orphaned
oak mount list --json # with dirty and unpushed counts β good for watching a fleet
oak finish --desc-file desc.md --json # inside a mount: describe, commit, push, then unmount
oak mount finish ./fix-auth --desc-file desc.md --json # same thing, from outside
oak mount end ./fix-auth # unmount and delete the directory; refuses if there's unpushed work
oak mount end ./fix-auth --force # β¦discarding uncommitted changes
oak mount end # end every mount under ~/oaktree
oak finish / oak mount finish check everything they can before changing anything, and only unmount once the push has succeeded. If a step fails the mount stays intact and the output names the command to run next β so finishing never silently loses work.
Setting up mounts#
Mounts use your operating system's own virtual-filesystem layer. Each needs a one-time setup per machine; no third-party kernel extension or driver is involved. Everything other than mounting β clone, commit, push, pull β works without it.
macOS: the Oak Mount app (macOS 26+)#
On macOS the filesystem runs inside a signed FSKit extension, OakFS, shipped in the Oak Mount app. The app only carries the extension: it must be installed and enabled once, but it doesn't need to be running, and one install serves every mount.
- Run your first
oak mount. If the installer didn't already, the CLI downloads Oak Mount, verifies its checksum, installs it in/Applications(or~/Applications), and opens it once so macOS registers the extension. - Enable it: System Settings β General β Login Items & Extensions β File System Extensions, then turn on OakFS. The Oak Mount window has a button that takes you there. No restart needed.
- Run
oak mountagain. From now on it attaches immediately.
If the extension is ever switched off, oak mount says so rather than failing mysteriously. Keep the app in /Applications.
Pick a destination outside ~/Documents, ~/Desktop, ~/Downloads, and iCloud Drive. macOS requires Full Disk Access for your terminal to mount inside those; somewhere like ~/oaktree avoids it.
Linux: FUSE#
- Install FUSE 3:
sudo apt install fuse3on Debian and Ubuntu, or your distro's equivalent. Oak mounts through thefusermount3helper it provides. - If your agent or editor runs as a different user, or in a sandbox, and needs to see into the mount, uncomment
user_allow_otherin/etc/fuse.conf. - On distros that gate FUSE behind a group (often
fuse), add yourself to it and log in again.
Windows: Projected File System#
Windows mounts use ProjFS β the same primitive GVFS and Scalar use for huge Git monorepos. Enable it once, from an elevated PowerShell:
Enable-WindowsOptionalFeature -Online -FeatureName Client-ProjFS -NoRestart
Or Settings β Apps β Optional features β Windows Projected File System.
Check it works#
oak mount acme/web /tmp/web-test && oak mount list
oak mount end /tmp/web-test
If the mount doesn't attach, the error almost always points back at one of the steps above.
Keep build output off the mount#
A mount is ideal for reading and editing source and poor for build output and tool caches. Keep those on your real disk:
- Redirect build directories.
CARGO_TARGET_DIR=/tmp/fix-auth-target cargo test; likewise fordist/,build/, and other generated directories. A build cache on a mount is slow and can produce baffling, wrong errors. - Don't install
node_moduleson a mount. On Linux, FUSE refuses to create symlinks and hard links (EPERM), which package managers rely on. Install outside the mount and point the tool at it. - Don't rewrite the whole tree at once. A repo-wide formatter run, codemod, or huge
rm -rfcan wedge a mount. Scope formatters to what you changed (cargo fmt -p <crate>).
Troubleshooting#
| Symptom | Fix |
|---|---|
Commands fail with os error 22 | The mount is wedged. Commit and push what you can, then oak mount end --force <dir> and mount again. --force discards uncommitted changes. |
oak mount list shows a mount as stale after a crash or reboot | Running oak mount again for it recovers it from its saved state. |
A mount shows as orphaned (its directory is gone) | oak mount forget --orphaned drops those registrations; their saved state is kept and reported. |
| A registration won't go away | oak mount forget <dir> removes it without touching on-disk state (--force if it looks live). |
Mount state lives under ~/.oak/mounts/ (override with OAK_MOUNTS_ROOT).
Mounts, clones, or sparse clones?#
| Mount | Clone | Sparse clone | |
|---|---|---|---|
| Time to first edit on a huge repo | Seconds | Full download | Download of the subtree |
| Files on disk | Only what's been read | Everything | Only the cone |
| Needs OS setup | Yes | No | No |
| Good for builds | Keep output off the mount | Yes | Yes |
| Can merge from it | No | Yes | Yes |
For a plain on-disk checkout of part of a monorepo, see Sparse clones. To run many agents across an org's repos, see Agent spaces.