Work on a local directory
This page copies your project into a sandbox with --local, as it is on your disk instead of a clone of its repo, and brings the agent’s changes back into the same files as uncommitted changes. It also covers droneship undo, which puts the sandbox’s files back the way an earlier snapshot had them.
Clone or copy in
Section titled “Clone or copy in”By default, droneship run claude clones your repo’s origin at your current branch, so uncommitted work and unpushed commits aren’t in the sandbox. --local sends your files as they are on your disk instead:
- Inside a git repo, it copies the whole repo from its top level, even when you run it from a subdirectory.
- Outside git, it copies the nearest parent directory you copied in before, or else the directory you’re in.
Your home directory, any directory above it and / are refused with <directory> cannot be a workspace; run droneship from a project directory. So are credential directories and anything inside them (~/.ssh, ~/.aws, ~/.gnupg, ~/.kube, ~/.docker, ~/.azure, ~/.claude, ~/.droneship and ~/.forge), with <directory> holds credentials and cannot be a workspace.
| Clone (default) | --local |
|
|---|---|---|
| Use it for | A GitHub repo with your work pushed | Uncommitted or unpushed work, or a directory that isn’t a git repo |
| The sandbox gets | A fresh clone of origin at your current branch |
Your repo or directory as it is on disk, including uncommitted changes and new files |
| The work comes back | As a branch: droneship pull, or a pull request with droneship pr |
Into your files, as uncommitted changes: droneship pull |
Snapshots and droneship undo |
No | Yes |
--local works with claude and codex, in your terminal.
-
Start Claude on your project.
Terminal window cd ~/src/my-projectdroneship run claude --localThe first time, the CLI lists what it will send and what stays on your machine, and asks before anything leaves:
Copy /home/you/src/my-project into the sandbox?114 files, 1.2 MBkept on this machine (secrets): .envnot sent (dependency caches): .mypy_cache, .pytest_cache, .ruff_cache, .tox, .venv, __pycache__, node_modules, target, venvContinue? [y/N]:Your answer is remembered for this directory.
--yesanswers it for you, and is required when there’s no terminal. Files that.gitignoreexcludes stay behind unless git tracks them. The repo’s.gitgoes in, so the agent has your history, with two exceptions. In a git worktree, whose history lives outside it, the sandbox gets the files without git, and the CLI says so. A.git/configthat holds a credential (a remote URL with a user or token in it, or anhttp.extraheader) stops the copy-in until you remove it. What stays on your machine lists the rest. -
Work with Claude as usual.
While the agent works, the sandbox snapshots the directory every 5 minutes, when something changed. Set the interval with
--snapshot-every(2m,30s, or0to turn it off). It’s remembered for this directory:Terminal window droneship run claude --local --snapshot-every 2m -
Come back to it.
Terminal window droneship run claudeYou don’t need
--localagain. A directory you copied in stays copied in:droneship run claudeanddroneship resume claudehere use its sandbox and saved workspace. Each launch or reattach sends what you changed here since the last copy-in.If the agent had also changed one of those files, your version replaces the agent’s, and the CLI names the files and the folder in the sandbox where it saved the agent’s copies. The sandbox snapshots its files first, so
droneship undocan bring the agent’s version back.If git’s own data changed on both sides, for example because the agent committed in the sandbox and you committed here, the sandbox’s git data is replaced by yours, and the CLI prints
the agent's commits are saved in <path>, a folder in the sandbox. Snapshots leave out.git, sodroneship undocan’t bring those commits back: look for them in that folder. -
See what the agent changed.
Terminal window droneship diffIt shows what changed in the sandbox since your last copy-in or pull. On a terminal it opens in your pager, and
droneship diff > agent-work.patchwrites a patch instead.droneship diff --statlists only the files. -
Bring the changes into your files.
Terminal window droneship pull --dry-rundroneship pull--dry-runlists the files that would change.pullasks before it writes anything:This changes 3 file(s) in /home/you/src/my-project. Review them with git afterwards.Apply them? [y/N]:The changes arrive as if the agent had made them here. A commit the agent made stays in the sandbox: only its file changes come back. The pull’s closing line tells you which of these happened:
- Staged. In a git repo, git’s 3-way apply merges the changes with yours where it can and stages them. The pull ends with
review with git diff --cached, andgit restore --staged --worktree <path>drops a file you don’t want. - Not staged. If you had unstaged edits to those files, or git doesn’t track some of them, the changes land in your files unstaged, the CLI says why, and the pull ends with
review with git status. Changes to files inside a nested repo also land unstaged, withinside the nested repo(s) <path> the changes are in your files but not staged. - Conflicts. Where git can’t merge, it leaves conflict markers, and the pull says
The pull is not finished. Your files stay as git left them and the sandbox keeps all of the agent’s changes, sodroneship diffstill shows them. Resolve the markers,git addeach file, then rundroneship run claudeto copy your resolution in. - Nothing changed. If your own edits are too far from the agent’s for git to match them, the pull changes nothing and asks you to commit or stash yours, then pull again.
In a directory with no git, the changes apply in place with nothing staged, and a change that doesn’t fit your files makes the pull stop without changing anything.
--yesskips the question, and is required when there’s no terminal. - Staged. In a git repo, git’s 3-way apply merges the changes with yours where it can and stages them. The pull ends with
-
Undo the agent’s changes in the sandbox.
Terminal window droneship undoIt lists the snapshots newest first: when each was taken, why (
copy-in,interval,before overwrite,before undo,undo,pulled) and the files it changed. Pick one, check the preview, and confirm. To put back one file or directory, name it:droneship undo src/api/handlers.py.--to N --yespicks snapshotNwithout asking.Undo changes the sandbox’s files only. It snapshots them first, so an undo can itself be undone, and a commit the agent made stays. Snapshots leave out
.git, so undo can’t bring back commits that a later copy-in replaced (step 3). Rundroneship pullafterwards to bring the result into your files.
What stays on your machine
Section titled “What stays on your machine”These never cross to the sandbox, and a pull never writes them back:
- Secrets:
.envand.env.*(but.env.example,.env.sampleand.env.templateare sent),*.pem,*.key,*.p12,*.pfx, SSH private keys (id_rsa*,id_ed25519*and the like),.netrcand.pypirc. They stay even when git tracks them. - Dependency caches:
node_modules,.venv,venv,__pycache__,.mypy_cache,.pytest_cache,.ruff_cache,.toxandtarget. - Files over 100 MB. If git tracks one, the CLI names it and asks before copying in without it, on every launch.
.git, on the way back. The sandbox gets your history, but its commits and branches don’t come back withpull.
A directory over 1 GB or 1000 files (not counting .git’s files) is refused, with the largest files or fullest directories named.
Go back to a clone
Section titled “Go back to a clone”--clone clones the repo, even in a directory you copied in, and is remembered like --local: later runs here clone too, until you pass --local again.
droneship run claude --cloneThe copied-in workspace stays, so --local later picks it back up, with its files and snapshots. To delete it, run droneship workspace delete in this directory (Workspaces).
When a launch copies the directory in because that’s what you chose last time, rather than because you passed --local, it says so in one line:
Copying this directory in, as it was the last time here (--clone to clone its repo instead).The CLI decides where the files come from in this order:
--localor--cloneon the command line.- The
DRONESHIP_WORKSPACE_SOURCEenvironment variable,localorclone. Set it as a default for scripts. - What you passed last time in this directory,
--localor--clone. - Otherwise, a clone.
A -p task always clones, even in a directory you copied in. So does --ref when the copy-in comes from step 2 or 3: the launch clones that branch, for this launch only, and says so:
--ref my-branch: cloning that branch for this launch.With --local on the command line, --ref is refused instead (next section).
When --local is refused
Section titled “When --local is refused”--local stops with an error rather than cloning instead:
| With | Message |
|---|---|
-p |
a -p task always starts on a fresh clone (the agent starts before a copy-in could land); drop --local |
--repo |
--repo clones that repo; --local copies this directory. Pick one |
--no-repo |
--no-repo starts empty; --local copies this directory. Pick one |
--ref |
--ref picks a branch to clone; --local copies this directory as it is. Check the branch out here first, or drop --local |
--clone |
--local copies this directory in; --clone clones its repo. Pick one |
--id, naming a sandbox that holds another tree |
<id> does not hold this directory's workspace, so nothing could be copied into it. Drop --id to use (or start) this directory's sandbox |
--ephemeral, in a directory never copied in |
this directory has never been copied in, and an ephemeral launch saves nothing, so `droneship pull` and `undo` could not find the agent's work. Drop --ephemeral |
The CLI prints each one after Invalid value for --local with <flag>: (Invalid value for --local: for -p). For example:
Invalid value for --local with --repo: --repo clones that repo; --local copies this directory. Pick oneIn a directory you copied in before, --local --ephemeral works: it starts a sandbox that saves nothing when it goes. Pull its work before it stops.
droneship undo in a directory that was never copied in says so. In a checkout with an origin remote, it names the repo:
This directory's workspace is a clone of https://github.com/you/my-project. Snapshots and undo exist only for a directory copied in with droneship run claude --local. For a clone, droneship diff and droneship pull bring the agent's work back.Elsewhere, the first sentence is This directory has never been copied into a sandbox.
More: droneship run, droneship diff, droneship pull, droneship undo.
- Review and land the agent’s work: the clone path, with a branch and a pull request.
- Workspaces: what a saved workspace keeps, and how to delete it.
- Pick up where it left off: reopen a past conversation.