CLI Reference¶
Setup¶
Set the repository once per shell session:
export VOST_REPO=/path/to/repo.git
Or pass --repo/-r per command. Use --branch/-b to target a branch (default: repo's current branch).
Pass -v before any command for status messages on stderr.
Command index¶
| Category | Commands |
|---|---|
| Repository Management | init, destroy, gc, pack |
| Everyday Commands | cp, sync, ls, cat, hash, rm, mv, write |
| History | log, diff, cmp, undo, redo, reflog |
| Refs | branch, tag, note |
| Archives | archive_out / archive_in, zip / unzip / tar / untar |
| Mirror | backup, restore |
| Server | serve, gitserve, mount |
Repo paths and the : prefix¶
Commands like cp and sync work with both local files and files inside the repo. A leading : marks a repo path. Without it, the argument is treated as a local filesystem path.
| Syntax | Meaning |
|---|---|
file.txt |
Local file on disk |
:file.txt |
Repo file on the current branch |
: |
Repo root on the current branch |
:data/ |
Repo directory (trailing / = contents mode in cp) |
main:file.txt |
Repo file on the main branch |
main: |
Repo root on main |
v1.0:data/file |
Repo file on the v1.0 tag (read-only) |
main~3:file.txt |
3 commits back on main |
~2:file.txt |
2 commits back on the current branch |
When is : required?¶
cp,sync,mv-- the:is how the command knows which arguments are repo paths and which are local paths. It is required.ls,cat,rm,write-- arguments are always repo paths, so the:is optional.vost cat file.txtandvost cat :file.txtare equivalent. However, the:is required to use explicit ref syntax (main:file.txt).hash,log,diff-- a bare string (no:) is treated as a ref (branch, tag, or commit hash), not a path. Use:pathfor repo paths:vost hash main= commit hash,vost hash :file.txt= blob hash.
Direction detection in cp¶
The : prefix on each argument determines the copy direction:
vost cp file.txt : # local -> repo (disk to repo)
vost cp :file.txt ./out # :repo -> local (repo to disk)
vost cp :a.txt :backup/ # :repo -> :repo (repo to repo)
vost cp main:a.txt dev:backup/ # cross-branch repo to repo
Writing to refs¶
Only branches are writable. Tags, commit hashes, and historical commits (~N) are read-only:
vost cp file.txt dev: # OK -- writes to dev branch
vost cp file.txt v1.0: # ERROR -- cannot write to a tag
vost cp file.txt main~1: # ERROR -- cannot write to history
For the full path syntax specification, see Path Syntax.
Repository Management¶
init¶
Create a new bare git repository.
vost init # or --repo <path>
vost init --branch dev
vost init -f # destroy and recreate
| Option | Description |
|---|---|
--branch, -b |
Initial branch (default: main). |
-f, --force |
Destroy existing repo and recreate. |
destroy¶
Remove a bare git repository.
vost destroy # fails if repo has data
vost destroy -f # force
gc¶
Clean up temporary files and pack loose objects. Does not require git.
vost gc
pack¶
Pack loose objects into a packfile. Consolidates loose git objects for better I/O performance and disk usage. Does not require git.
vost pack
Everyday Commands¶
cp¶
Copy files and directories between disk and repo. The last argument is the destination; all preceding arguments are sources. Prefix repo-side paths with :.
# Disk to repo
vost cp file.txt : # keep name at repo root
vost cp file.txt :dest/file.txt # explicit dest
vost cp f1.txt f2.txt :dir # multiple files
vost cp ./mydir :dest # directory (name preserved)
vost cp ./mydir/ :dest # contents mode (trailing /)
vost cp './src/*.py' :backup # glob
# Pivot (/./): preserve partial source path
vost cp /data/./logs/app :backup # → backup/logs/app/...
vost cp /data/./logs/app/ :backup # → backup/logs/...
vost cp /home/user/./projects/f.txt :bak # → bak/projects/f.txt
# Repo to disk
vost cp :file.txt ./local.txt
vost cp ':docs/*.md' ./local-docs
# Pivot (/./): preserve partial repo path
vost cp ':data/./logs/app' ./backup # → backup/logs/app/...
vost cp ':data/./logs/app/' ./backup # → backup/logs/...
vost cp ':src/./lib/utils.py' ./dest # → dest/lib/utils.py
# Options
vost cp -n ./mydir :dest # dry run
vost cp --delete ./src/ :code # remove extra repo files
vost cp --ref v1.0 :data ./local # from tag/branch/hash
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--ref |
Branch, tag, or commit hash to read from. |
--path |
Latest commit that changed this path. |
--match |
Latest commit matching message pattern (*, ?). |
--before |
Latest commit on or before this date (ISO 8601). |
--back N |
Walk back N commits from tip. |
-m, --message |
Commit message (supports placeholders). |
--type |
blob or executable (default: auto-detect from disk permissions). |
--follow-symlinks |
Dereference symlinks (disk→repo only). |
-n, --dry-run |
Preview without writing. |
--ignore-existing |
Skip existing destination files. |
--delete |
Delete dest files not in source (rsync --delete). Excluded files are preserved — see Exclude patterns. |
--no-glob |
Treat source paths as literal (no * or ? expansion). |
--exclude PATTERN |
Exclude files matching pattern (gitignore syntax, repeatable; disk→repo only; see Exclude patterns). |
--exclude-from FILE |
Read exclude patterns from file (disk→repo only; see Exclude patterns). |
--ignore-errors |
Skip failed files and continue. |
-c, --checksum |
Compare files by checksum instead of mtime (slower, exact). |
--parent REF |
Additional parent ref (branch/tag/hash). Repeatable. Advisory only — no tree merging (disk→repo only). |
--no-create |
Don't auto-create the repo. |
--tag |
Create a tag at the resulting commit (disk→repo only). |
--force-tag |
Overwrite tag if it already exists. |
Copy behavior¶
| Source | Result at :dest |
|---|---|
file.txt |
dest/file.txt |
dir |
dest/dir/... (name preserved) |
dir/ |
dest/... (contents poured, including dotfiles) |
'dir/*' |
dest/a.txt ... (glob, no dotfiles) |
'**/*.py' |
dest/matched... (recursive glob) |
/base/./sub/dir |
dest/sub/dir/... (pivot) |
/base/./sub/dir/ |
dest/sub/... (pivot + contents) |
/./ pivot¶
An embedded /./ in a source path (rsync -R style) splits the path into a locator and a preserved suffix. Everything before /./ locates the source (on disk or in the repo); everything after becomes the destination-relative path. Works in both disk→repo and repo→disk directions.
A leading ./ (e.g. ./mydir) is a normal relative path and does not trigger pivot mode.
Glob patterns (*, ?, **) in the segment after /./ are not supported — use them before the pivot or as separate sources.
sync¶
Make one path identical to another (like rsync --delete).
vost sync ./dir # sync dir to repo root
vost sync ./local :repo_path # disk → repo
vost sync :repo_path ./local # repo → disk
vost sync -n ./local :repo_path # dry run
vost sync :data ./local --ref v1.0 # from tag
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--ref |
Branch, tag, or commit hash. |
--path |
Latest commit that changed this path. |
--match |
Latest commit matching message pattern. |
--before |
Latest commit on or before this date. |
--back N |
Walk back N commits from tip. |
-m, --message |
Commit message (supports placeholders). |
-n, --dry-run |
Preview without writing. |
--exclude PATTERN |
Exclude files matching pattern (gitignore syntax, repeatable; disk→repo only; see Exclude patterns). |
--exclude-from FILE |
Read exclude patterns from file (disk→repo only; see Exclude patterns). |
--gitignore |
Read .gitignore files from source tree (disk→repo only). |
--ignore-errors |
Skip failed files. |
-c, --checksum |
Compare files by checksum instead of mtime (slower, exact). |
--parent REF |
Additional parent ref (branch/tag/hash). Repeatable. Advisory only — no tree merging (disk→repo only). |
--no-create |
Don't auto-create the repo. |
--tag |
Create a tag at the resulting commit (disk→repo only). |
--force-tag |
Overwrite tag if it already exists. |
--watch |
Watch for changes and sync continuously (disk→repo only). |
--debounce MS |
Debounce delay in ms for --watch (default: 2000). |
Watch mode¶
With --watch, continuously watches the local directory and syncs on changes:
vost sync --watch ./dir :data
vost sync --watch --debounce 5000 ./dir
vost sync --watch -c ./src :code # checksum mode
Requires: pip install vost[cli]
ls¶
List files and directories. Accepts multiple paths and glob patterns — results are coalesced and deduplicated.
vost ls # root
vost ls subdir # subdirectory
vost ls --ref v1.0 # at a tag
vost ls '*.txt' # glob (quote to avoid shell expansion)
vost ls 'src/*.py' # glob in subdirectory
vost ls '**/*.py' # ** matches all depths
vost ls 'src/**/*.txt' # ** under a prefix
vost ls '*.txt' '*.py' # multiple globs
vost ls :src :docs # multiple directories
vost ls -R # all files recursively
vost ls -R :src :docs # recursive under multiple dirs
vost ls -R 'src/*' # glob + recursive expansion
| Option | Description |
|---|---|
-R, --recursive |
List all files recursively with full paths. |
-l, --long |
Show file sizes, types, and hashes. |
--full-hash |
Show full 40-character hashes (default: 7-char; requires -l). |
--format |
Output format: text (default), json, jsonl. |
--no-glob |
Disable glob expansion — treat * and ? as literal characters. |
-b, --branch |
Branch (default: current branch). |
--ref, --path, --match, --before, --back |
Snapshot filters. |
cat¶
Print file contents to stdout. Accepts multiple paths — output is concatenated.
vost cat file.txt
vost cat file.txt --ref v1.0
vost cat :a.txt :b.txt # concatenate multiple files
vost cat main:f.txt dev:f.txt # files from different refs
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--ref, --path, --match, --before, --back |
Snapshot filters. |
Diffing with process substitution¶
Use shell process substitution (<(...)) to diff any two snapshots with standard diff:
diff <(vost cat :file.py) <(vost cat ~1:file.py) # vs previous commit
diff <(vost cat :file.py) <(vost cat tag-name:file.py) # vs any tag
diff <(vost cat ~3:file.py) <(vost cat ~0:file.py) # any two snapshots
hash¶
Print the SHA hash of a commit, tree, or blob. An optional TARGET argument is interpreted as a ref (bare string) or ref:path (with colon).
vost hash # current branch commit hash
vost hash main # main branch commit hash
vost hash v1.0 # tag commit hash
vost hash ~3 # 3 commits back
vost hash :config.json # blob hash on current branch
vost hash main:src/ # tree hash of directory
vost hash main~1:file.txt # blob hash from one commit back
vost hash --match "deploy*" # commit matching message
vost hash :file.txt --path file.txt # blob hash at commit that last changed file
A bare string (no :) is treated as a ref — branch name, tag name, or commit hash. With :path, the object hash at that path is printed instead of the commit hash.
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--format |
Output format: text (default), json, jsonl. |
--ref, --path, --match, --before, --back |
Snapshot filters. |
rm¶
Remove files from the repo. Accepts multiple paths and glob patterns. Directories require -R.
vost rm old-file.txt
vost rm old-file.txt -m "Clean up"
vost rm ':*.txt' # glob (quote for shell)
vost rm -R :dir # directory
vost rm -n :file.txt # dry run
vost rm :a.txt :b.txt # multiple
| Option | Description |
|---|---|
-R, --recursive |
Remove directories recursively. |
-n, --dry-run |
Show what would change without writing. |
--no-glob |
Treat source paths as literal (no * or ? expansion). |
-b, --branch |
Branch (default: current branch). |
-m, --message |
Commit message. |
--parent REF |
Additional parent ref (branch/tag/hash). Repeatable. Advisory only — no tree merging. |
--tag |
Create a tag at the resulting commit. |
--force-tag |
Overwrite tag if it already exists. |
mv¶
Move/rename files within the repo. All arguments are repo paths (colon prefix required). The last argument is the destination.
vost mv :old.txt :new.txt # rename
vost mv ':*.txt' :archive/ # glob move
vost mv -R :src :dest # move directory
vost mv :a.txt :b.txt :dest/ # multiple -> dir
vost mv -n :old.txt :new.txt # dry run
vost mv dev:old.txt dev:new.txt # explicit branch
| Option | Description |
|---|---|
-R, --recursive |
Move directories recursively. |
-n, --dry-run |
Show what would change without writing. |
--no-glob |
Treat source paths as literal (no * or ? expansion). |
-b, --branch |
Branch (default: current branch). |
-m, --message |
Commit message. |
--parent REF |
Additional parent ref (branch/tag/hash). Repeatable. Advisory only — no tree merging. |
--tag |
Create a tag at the resulting commit. |
--force-tag |
Overwrite tag if it already exists. |
All paths must target the same branch. Cross-branch moves are not supported — use cp + rm instead.
write¶
Write stdin to a file in the repo.
echo "hello" | vost write file.txt
cat data.json | vost write :config.json
cat image.png | vost write :assets/logo.png -m "Add logo"
# Passthrough (tee mode) — data flows to stdout AND into the repo
cmd | vost write log.txt -p | grep error
tail -f /var/log/app.log | vost write log.txt --passthrough
| Option | Description |
|---|---|
-p, --passthrough |
Echo stdin to stdout (tee mode for pipelines). |
-b, --branch |
Branch (default: current branch). |
-m, --message |
Commit message. |
--parent REF |
Additional parent ref (branch/tag/hash). Repeatable. Advisory only — no tree merging. |
--no-create |
Don't auto-create the repo. |
--tag |
Create a tag at the resulting commit. |
--force-tag |
Overwrite tag if it already exists. |
History¶
log¶
Show commit history. An optional TARGET argument selects the ref to start from. A bare string (no :) is treated as a ref; with : it supports ref:path syntax.
vost log
vost log main # log of main branch
vost log v1.0 # log starting from tag
vost log main~3 # log from 3 commits back on main
vost log --path file.txt
vost log --match "deploy*"
vost log --before 2024-06-01
vost log --format json # or jsonl
# ref:path syntax
vost log main:config.json # --ref main --path config.json
vost log main~3: # --ref main --back 3
vost log ~3:config.json # --back 3 --path config.json
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--ref |
Start from branch, tag, or hash. |
--path |
Commits that changed this path. |
--match |
Commits matching message pattern. |
--before |
Commits on or before this date. |
--back N |
Walk back N commits from tip. |
--format |
text (default), json, jsonl. |
Text format: SHORT_HASH ISO_TIMESTAMP MESSAGE
diff¶
Compare current branch HEAD against another snapshot. An optional BASELINE argument selects the comparison target. A bare string (no :) is treated as a ref; with : it supports ref:path syntax. Output uses git-style --name-status format (old → new by default):
A new-file.txt # Added since baseline
M changed-file.txt # Modified since baseline
D removed-file.txt # Deleted since baseline
vost diff dev # what's different vs dev branch
vost diff v1.0 # what changed since tag
vost diff ~3 # what changed in last 3 commits
vost diff main~2 # vs 2 commits back on main
vost diff --before 2025-01-01 # what changed since Jan 1
vost diff --back 3 --reverse # swap direction (new → old)
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--format |
Output format: text (default), json, jsonl. |
--ref, --path, --match, --before, --back |
Snapshot filters (select baseline). |
--reverse |
Swap comparison direction (A↔D flipped, M stays M). |
cmp¶
Compare two files by content hash. Files can be repo paths, local disk paths, or a mix. Exit code follows POSIX cmp convention: 0 = identical, 1 = different.
vost cmp :file1.txt :file2.txt # two repo files
vost cmp main:f.txt dev:f.txt # cross-branch
vost cmp main~3:f.txt main:f.txt # ancestor
vost cmp :data.bin /tmp/data.bin # repo vs disk
vost cmp /tmp/a.txt /tmp/b.txt # two disk files
vost -v cmp :old.txt :new.txt # verbose — show hashes on stderr
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--ref, --path, --match, --before, --back |
Snapshot filters. |
Exit codes:
| Code | Meaning |
|---|---|
0 |
Files are identical (same blob SHA). |
1 |
Files differ. |
With -v (verbose, before the subcommand), both hashes are printed to stderr.
undo¶
vost undo # back 1 commit
vost undo 3 # back 3 commits
vost undo -b dev # undo on 'dev' branch
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
redo¶
vost redo # forward 1 reflog step
vost redo 2 # forward 2 steps
vost redo -b dev # redo on 'dev' branch
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
reflog¶
vost reflog
vost reflog -n 10 # last 10 entries
vost reflog -b dev # entries for 'dev' branch
vost reflog --format json
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
-n, --limit |
Limit number of entries shown. |
--format |
text (default), json, jsonl. |
Refs¶
branch¶
vost branch # list
vost branch list # same
vost branch set dev # fork from default branch
vost branch set dev --ref main # fork from specific ref
vost branch set dev --ref main --path config.json
vost branch set dev -f # overwrite existing
vost branch set dev --empty # empty orphan branch
vost branch exists dev # exit 0 if exists, 1 if not
vost branch current # show current branch
vost branch current -b dev # set current branch to 'dev'
vost branch delete dev
vost branch hash main # tip commit SHA
vost branch hash main --back 3 # 3 commits before tip
vost branch hash main --path config.json # last commit that changed file
# Squash and append
vost branch set snapshot --ref main --squash # main's tree, no history
vost branch set main --squash -f # squash main in place
vost branch set main --append --ref feature # append feature's tree onto main
branch set options¶
| Option | Description |
|---|---|
-b, --branch |
Source branch (default: current branch). |
-f, --force |
Overwrite if branch already exists. |
--empty |
Create an empty root branch (no parent commit). Cannot combine with other options. |
--squash |
Collapse source to a single commit (no history). |
--append |
Append source tree as a new commit on the target branch's tip. Requires the branch to exist. |
--ref, --path, --match, --before, --back |
Snapshot filters. |
branch list options¶
| Option | Description |
|---|---|
--format |
Output format: text (default), json, jsonl. |
branch current¶
With no arguments, prints the current branch name. With -b NAME, sets the current branch (HEAD) to NAME. Note: -b here means "set current branch to" rather than its usual "operate on branch" meaning.
| Option | Description |
|---|---|
--format |
Output format: text (default), json, jsonl. |
branch exists¶
Exits with code 0 if the branch exists, 1 if it does not. No output.
branch hash options¶
The positional NAME selects the branch. --ref is accepted but has no effect — use --path, --match, --before, and --back to select a specific commit.
| Option | Description |
|---|---|
--format |
Output format: text (default), json, jsonl. |
--path, --match, --before, --back |
Snapshot filters (see Snapshot filters). |
tag¶
vost tag # list
vost tag list # same
vost tag set v1.0 # tag from default branch
vost tag set v1.0 --ref main # tag from specific ref
vost tag set v1.0 --before 2024-06-01 # tag a historical commit
vost tag set v1.0 -f # overwrite existing tag
vost tag exists v1.0 # exit 0 if exists, 1 if not
vost tag hash v1.0 # commit SHA
vost tag delete v1.0
tag set options¶
| Option | Description |
|---|---|
-b, --branch |
Source branch (default: current branch). |
-f, --force |
Overwrite if tag already exists. |
--ref, --path, --match, --before, --back |
Snapshot filters. |
tag list options¶
| Option | Description |
|---|---|
--format |
Output format: text (default), json, jsonl. |
tag hash options¶
| Option | Description |
|---|---|
--format |
Output format: text (default), json, jsonl. |
tag exists¶
Exits with code 0 if the tag exists, 1 if it does not. No output.
note¶
Manage git notes on commits. Notes are stored in namespaces (default: commits).
vost note get [TARGET] # get note (default: current branch)
vost note set [TARGET] "text" # set note (default: current branch)
vost note delete [TARGET] # delete note (default: current branch)
vost note list # list commits that have notes
note get / set / delete¶
Operate on a specific commit. TARGET can be a 40-char hex commit hash, a branch/tag name (resolved to its tip commit), : (current branch), or ref: (strip trailing colon). When TARGET is omitted, the current branch is used.
| Option | Description |
|---|---|
-N, --namespace |
Notes namespace (default: commits). |
note list¶
List all commit hashes that have notes in the given namespace.
| Option | Description |
|---|---|
-N, --namespace |
Notes namespace (default: commits). |
--format |
Output format: text (default), json, jsonl. |
Archives¶
archive_out / archive_in¶
Format auto-detected from extension (.zip, .tar, .tar.gz, .tar.bz2, .tar.xz).
vost archive_out out.zip
vost archive_out out.tar.gz
vost archive_out - --format tar | gzip > a.tar.gz # stdout
vost archive_in data.zip
vost archive_in data.tar.gz
vost archive_in --format tar < archive.tar # stdin
archive_out options¶
| Option | Description |
|---|---|
--format |
zip or tar (overrides auto-detect; required for stdout). |
-b, --branch |
Branch (default: current branch). |
--ref, --path, --match, --before, --back |
Snapshot filters. |
archive_in options¶
| Option | Description |
|---|---|
--format |
zip or tar (overrides auto-detect; required for stdin). |
-b, --branch |
Branch (default: current branch). |
-m, --message |
Commit message. |
--no-create |
Don't auto-create the repo. |
--tag |
Create a tag at the resulting commit. |
--force-tag |
Overwrite tag if it already exists. |
zip / unzip / tar / untar¶
Aliases with a fixed format. Same options as archive_out/archive_in (including --tag / --force-tag for import commands).
vost zip out.zip # = archive_out --format zip
vost unzip data.zip # = archive_in --format zip
vost tar out.tar.gz # = archive_out --format tar
vost untar data.tar.gz # = archive_in --format tar
Mirror¶
backup¶
Push refs to a remote URL or write a bundle file. Without --ref this is a full mirror: remote-only refs are deleted.
vost backup https://github.com/user/repo.git
vost backup /path/to/other.git
vost backup -n https://github.com/user/repo.git # dry run
vost backup /tmp/backup.bundle # bundle file
vost backup backup.bundle --ref main --ref v1.0 # only specific refs
restore¶
Fetch refs from a remote URL or import a bundle file. Restore is additive: refs are added and updated but local-only refs are never deleted.
vost restore https://github.com/user/repo.git
vost restore -n https://github.com/user/repo.git # dry run
vost restore /tmp/backup.bundle # bundle file
vost restore backup.bundle --ref main # only specific refs
HEAD (the current branch) is not restored; use vost branch current -b NAME afterwards if needed.
| Option | Description |
|---|---|
-n, --dry-run |
Preview without transferring data. |
--ref REF |
Ref to include (repeatable). Short names resolved to branches/tags. Omit for all refs. |
--format bundle |
Force bundle format (auto-detected from .bundle extension). |
--output-format |
Display format for --dry-run output: text (default), json, jsonl. |
--no-create |
Don't auto-create the repo (restore only). |
Server¶
serve¶
Serve repository files over HTTP with content negotiation. Content is resolved live on each request — new commits are visible immediately. Browsers see HTML directory listings and raw file contents; API clients requesting Accept: application/json get JSON metadata.
vost serve # serve HEAD branch at http://127.0.0.1:8000/
vost serve -b dev # serve a different branch
vost serve --ref v1.0 # serve a tag snapshot
vost serve --back 3 # serve 3 commits before tip
vost serve --all # multi-ref: /<branch-or-tag>/<path>
vost serve --all --cors # multi-ref with CORS headers
vost serve --base-path /data -p 9000 # mount under /data on port 9000
vost serve --open --no-cache # open browser, disable caching
vost serve -q # suppress per-request log output
| Option | Description |
|---|---|
--host |
Bind address (default: 127.0.0.1). |
-p, --port |
Port to listen on (default: 8000, use 0 for OS-assigned). |
-b, --branch |
Branch (default: current branch). |
--ref, --path, --match, --before, --back |
Snapshot filters. |
--all |
Multi-ref mode: expose all branches and tags via /<ref>/<path>. |
--cors |
Add Access-Control-Allow-Origin: * and related CORS headers. |
--immutable |
Set Cache-Control: public, immutable, max-age=31536000. Ideal for content-addressed data. |
--max-age N |
Set Cache-Control: public, max-age=N (seconds). Overridden by --no-cache or --immutable. |
--no-cache |
Send Cache-Control: no-store on every response (disables caching entirely). |
--base-path PREFIX |
URL prefix to mount under (e.g. /data). |
--upstream URL |
Redirect (302) to upstream server on blob cache miss. Enables CDN-like server hierarchies. |
--open |
Open the URL in the default browser on start. |
-q, --quiet |
Suppress per-request log output. |
Modes:
- Single-ref (default): serves one branch or snapshot. URLs are plain repo paths (
/file.txt,/dir/). - Multi-ref (
--all): first URL segment selects the branch or tag (/main/file.txt,/v1/dir/). The root (/) lists all branches and tags.
Content-addressed blob access:
Two routes provide direct access to git blobs by SHA hash, bypassing tree/path resolution:
/_/blobs/{hash}— explicit blob access by 40-char hex SHA. Returns404if not found (or redirects to--upstream)./{hash}— shorthand: if the URL path is exactly 40 hex characters, tries blob lookup first, falls back to normal path/ref routing.
Both support Range requests, ETag/304, and Accept: application/json (returns {"hash": "...", "size": N, "type": "blob"}). Ideal for kerchunk references: ["http://host/_/blobs/abc123...", 0, 1024].
Content negotiation:
Accept: application/jsonreturns JSON metadata (path, ref, size, hash, type, entries).- Otherwise: raw file bytes with MIME types, or HTML directory listings.
Caching:
- File responses use per-blob ETags (content hash), so caching survives commits to other files.
- Directory responses use commit-level ETags.
- Default:
Cache-Control: no-cache(revalidate on each request, 304 on match). --immutable:Cache-Control: public, immutable, max-age=31536000(1 year, ideal for content-addressed data).--max-age N:Cache-Control: public, max-age=N.--no-cache:Cache-Control: no-store(disable caching entirely).- Priority:
--no-cache>--immutable>--max-age> default.
Range requests:
All file and blob responses include Accept-Ranges: bytes and support HTTP Range requests (206 Partial Content).
Response headers:
ETagis set on all 200 file/directory responses (blob hash for files, commit hash for directories).- JSON, XML, GeoJSON, and YAML files are served as
text/plainso browsers display them inline.
gitserve¶
Serve the repository read-only over HTTP. Standard git clients can clone and fetch from the URL. Pushes are rejected.
vost gitserve # serve at 127.0.0.1:8000
vost gitserve -p 9000 # custom port
vost gitserve --host 0.0.0.0 -p 8080 # bind all interfaces
git clone http://127.0.0.1:8000/ # clone from another terminal
| Option | Description |
|---|---|
--host |
Bind address (default: 127.0.0.1). |
-p, --port |
Port to listen on (default: 8000, use 0 for OS-assigned). |
mount¶
Mount a branch or tag as a read-only FUSE filesystem. Requires pip install vost[fuse].
vost mount /tmp/mnt # mount current branch
vost mount /tmp/mnt -b dev # mount a different branch
vost mount /tmp/mnt --ref v1.0 # mount a tag
vost mount /tmp/mnt --back 2 # mount 2 commits before tip
vost mount /tmp/mnt -f # run in foreground
| Option | Description |
|---|---|
-b, --branch |
Branch (default: current branch). |
--ref, --path, --match, --before, --back |
Snapshot filters. |
-f, --foreground |
Run in foreground (default: daemonize). |
--debug |
Enable FUSE debug output. |
--nothreads |
Single-threaded mode. |
--allow-other |
Allow other users to access the mount. |
Appendix¶
Snapshot filters¶
Several commands accept filters to select a specific commit:
| Option | Description |
|---|---|
--ref REF |
Branch, tag, or commit hash. |
--path PATH |
Latest commit that changed this file. |
--match PATTERN |
Latest commit matching message pattern (*, ?). |
--before DATE |
Latest commit on or before this date (ISO 8601). |
--back N |
Walk back N commits from tip. |
Filters combine with AND. Available on cp, sync, ls, cat, log, diff, cmp, branch set, branch hash, tag set, archive_out, zip, tar, serve, mount.
Dry-run output format¶
+ :path/to/new-file (add)
~ :path/to/changed-file (update)
- :path/to/removed-file (delete)
Message placeholders¶
The -m option accepts placeholders that expand at commit time:
| Placeholder | Expands to |
|---|---|
{default} |
Full auto-generated message. |
{add_count} |
Number of additions. |
{update_count} |
Number of updates. |
{delete_count} |
Number of deletions. |
{total_count} |
Total changed files. |
{op} |
Operation name (cp, sync, rm, mv, ar (archive), or empty). |
vost cp dir/ :dest -m "Deploy: {default}"
vost sync ./src :code -m "Sync {total_count} files"
A message without { is used as-is. Unknown placeholders raise an error.
Exclude patterns¶
The --exclude and --exclude-from options use gitignore syntax:
| Pattern | Matches |
|---|---|
*.pyc |
Any .pyc file at any depth |
build/ |
Directories named build (not files) |
/build |
build at root only (anchored) |
!important.log |
Negation — un-excludes a previously excluded file |
__pycache__/ |
__pycache__ directories and all their contents |
Multiple --exclude flags combine. --exclude-from reads one pattern per line (blank lines and # comments are skipped).
--delete + --exclude interaction (rsync behavior):
When --delete and --exclude are combined, excluded files in the destination are preserved — they are not deleted. This matches rsync's behavior: excluded files are invisible to the operation in both source and destination.
# Example: sync code but leave .pyc files untouched in the repo
vost cp --delete --exclude '*.pyc' ./src/ :code
# Result: new/changed .py files are synced,
# .py files removed from disk are deleted from repo,
# .pyc files in the repo are left as-is.
The same rule applies to sync --exclude and --gitignore: files excluded by gitignore patterns are preserved in the destination when deletions occur.
The --gitignore flag (sync only) automatically reads .gitignore files from the source directory tree. Each .gitignore applies to files in its own directory and below. When active, .gitignore files themselves are excluded from the repo.
Dry-run commands¶
Available on: cp, sync, rm, mv, backup, restore.
Advisory parents¶
The --parent REF option (repeatable) adds extra parent commits without merging trees. The branch tip stays the first parent; advisory parents are appended. This records provenance (e.g. "this commit incorporates data from these sources") visible to git log --graph. Available on: write, rm, mv, cp, sync.
Tag-on-commit commands¶
The --tag and --force-tag options create a tag at the resulting commit. Available on: cp, sync, rm, mv, write, archive_in, unzip, untar.
Copy behavior¶
See Copy behavior in the cp section.
See also: Path Syntax | Python API Reference | CLI Tutorial | README