Share a directory with another repo
share publishes a directory so other repositories can copy it in. It tracks the source branch tip the way ship tracks a site, but consumers do not update on autosave. Someone (or a cron) must run share pull.
This is not a public HTTP URL. For a site people open in a browser, use Publish a site. This is not upload / download (those are one-time links for a person on a laptop).
Create requires repository owner. Pull requires write access on the consumer repository.
Before you start
Check your role in each repository before you run anything:
capabilities
In the source repo you need "role": "owner". In the consumer repo you need write access (owner or a write member). If you plan to schedule refreshes, the consumer also needs "can_schedule": true.
The folder you share has to exist on the source branch tip, not just on disk. Autosave usually takes care of that. If you just created the folder, run repo log -n 1 --path tools and confirm a commit comes back before you run share create.
Done looks like
share list in the source repo prints JSON that includes a share id. In the consumer repo, share pull SHARE_ID dest/ writes files into dest/. share status SHARE_ID in the consumer shows whether the last pull matches the source tip. Later share pull SHARE_ID (no dest) overwrites that same binding.
Worked example: vendor a tools/ folder
Job: repo A has tools/ that repo B should use. Source checkpoint does not fan out. B pulls when it wants a new copy.
1. Source repo (owner)
The path must be under $HOME, on the branch tip, and non-empty. Autosave usually already checkpointed.
share create --path tools --policy 644
--policy 644 lets any authenticated user pull (cross-repo). Default 600 is source owner only, so another repository cannot pull.
Commands print JSON to stdout. Copy the share id from that object. Every other command takes that id exactly as printed. A made-up or mistyped id fails right away with share status: invalid id (or share pull: invalid share id), so copy it rather than retyping it.
share list
share status SHARE_ID
share list is a JSON array of the shares created in this repo. A repo with no shares prints []. Use the same id on the consumer.
2. Consumer repo (write access)
First pull requires a destination path. It must be a folder you can write.
share pull SHARE_ID vendor/tools
Done: vendor/tools exists and matches the source tip at pull time. share bindings in this repo lists the install (the share id and the dest path it writes to). Before the first pull, share bindings prints [].
After the source repo edits tools/ and autosave moves the tip:
share pull SHARE_ID
Omitting dest reuses the bound path and overwrites. There is no merge.
3. Keep it current (optional)
Pulls stay manual unless you schedule them. Run this in the consumer repo. Scheduling needs write access there, not ownership. Read members cannot schedule jobs.
echo 'share pull SHARE_ID' | cron '15 6 * * *'
crontab -l
The job runs as whoever created it, so that identity needs write access in the consumer repo when it fires, and the share policy has to let it pull. To stop the refresh, find the job id in crontab -l and run crontab -r JOB_ID. To see whether past pulls worked:
runs list --kind scheduled_job
runs log JOB_ID
For a single refresh later instead of a recurring one, at takes a duration:
echo 'share pull SHARE_ID' | at +2h
See Run something every morning. There is no automatic fan-out on source checkpoint.
Flags and commands
share help
share help and share --help print the same usage.
| Command | What it does |
|---|---|
share create [--path PATH] [--branch B] [--policy MODE] | Owner. Share that folder on that branch. Default path is cwd. Default policy 600. |
share list | Shares created in this repo (JSON) |
share update ID --policy MODE | Change who may pull |
share delete ID | Drop the share. Existing consumer copies stay on disk until someone deletes them |
share pull ID [DEST] | Consumer. First time needs DEST. Later pulls may omit it |
share bindings | Installs in the current repo |
share status ID | Tip vs last pulled |
Policies (who may pull), same octal model as ship:
| Policy | Who can pull |
|---|---|
| 644 | Any authenticated user (cross-repo share) |
| 640 | Source repo owner or default-group members |
| 600 | Source repo owner only (default) |
--branch pins which source branch tip the share tracks. Omit it to use the current branch.
Failure modes
| What you see | What it means | What to do |
|---|---|---|
| Create denied | Owner-only | Run capabilities. If role is not owner, ask an owner to run share create |
share status: invalid id or share pull: invalid share id | The id is mistyped, made up, or from a share that was deleted | Copy the id again from share list in the source repo |
| Consumer cannot pull | Policy too tight, or no write access here | Source: share update ID --policy 644. Consumer: you need write in this repo |
| Pull asks for dest-path | First install in this repo | share pull ID vendor/tools |
| Consumer still has old files | Pulls are manual | share pull ID. Or cron. Do not wait for autosave |
cron refuses to schedule the pull | You are a read member in the consumer repo | Ask a write member or owner to schedule it, or pull by hand |
| Scheduled pull runs but the files do not change | Policy changed, the share was deleted, or the job identity lost write access | runs log JOB_ID shows the error. Fix the policy or the role, or crontab -r JOB_ID |
| Empty / invalid path | Cwd or --path not a non-empty folder under $HOME | Share a real directory that already has files on the branch tip |
You ran ship create for a library folder | That is an HTTP mount, not a copy into another repo | share create if the job is another repo copying files |
You used upload for a repo-to-repo copy | Upload is a person on a laptop | share create / share pull |
| You expected git history | Share copies the directory contents | Use Sync with GitHub if you need a git remote |
repo copy-path is a one-shot membership-gated graft. It has no share id and no pull tracking. Use share when the consumer should refresh later. All three arguments are required:
repo copy-path SOURCE_REPO_ID SOURCE_PATH DEST_PATH
See File transfer when the other side is a browser, and Publish a site when the other side is HTTP.