Python API Reference¶
from vost import GitStore, FS, Batch, WriteEntry, StaleSnapshotError, retry_write
from vost import ChangeReport, ChangeAction, ChangeActionKind, ChangeError, FileEntry, FileType
from vost import MirrorDiff, RefChange, ReflogEntry, Signature, WalkEntry
from vost import NoteDict, NoteNamespace, NotesBatch
from vost import ExcludeFilter, BlobOid, StatResult, disk_glob
GitStore¶
vost.GitStore(repo: _Repository, author: str, email: str)
¶
A versioned filesystem backed by a bare git repository.
Open or create a store with :meth:open. Access snapshots via
:attr:branches, :attr:tags, and :attr:notes.
branches = RefDict(self, 'refs/heads/')
instance-attribute
¶
tags = RefDict(self, 'refs/tags/')
instance-attribute
¶
notes = NoteDict(self)
instance-attribute
¶
open(path: str | Path, *, create: bool = True, branch: str | None = 'main', author: str = 'vost', email: str = 'vost@localhost', compression: int | None = None, big_file_threshold: int | None = None) -> GitStore
classmethod
¶
Open or create a bare git repository.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | Path
|
Path to the bare repository. |
required |
create
|
bool
|
If True (default), create the repo when it doesn't exist. If False, raise FileNotFoundError when missing. |
True
|
branch
|
str | None
|
Initial branch name when creating (default "main"). None to create a bare repo with no branches. |
'main'
|
author
|
str
|
Default author name for commits. |
'vost'
|
email
|
str
|
Default author email for commits. |
'vost@localhost'
|
compression
|
int | None
|
Zlib compression level for git objects (0-9). None uses the git default (6). 0 disables compression, which is ideal for pre-compressed data like Zarr chunks. |
None
|
big_file_threshold
|
int | None
|
Blobs larger than this (bytes) skip delta compression during packing. 0 means all blobs skip deltas. None uses the git default (512 MiB). |
None
|
fs(ref: str, *, back: int = 0) -> FS
¶
Get an FS snapshot for any ref (branch, tag, or commit hash).
Resolution order: branches → tags → commit hash. Writable for branches, read-only for tags and commit hashes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ref
|
str
|
Branch name, tag name, or commit hash (full or short). |
required |
back
|
int
|
Walk back N ancestor commits (default 0). |
0
|
Returns:
| Type | Description |
|---|---|
FS
|
FS snapshot for the resolved ref. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If ref cannot be resolved. |
read_by_hash(hash: str | bytes, *, offset: int = 0, size: int | None = None) -> bytes
¶
Read raw blob data by hash, bypassing tree/ref resolution.
This is the fastest path to blob data — no FS, no tree walk, just a direct object store lookup. Ideal for content-addressed access.
has_hash(hash: str | bytes) -> bool
¶
Check if a blob with the given hash exists in the object store.
pack(*, progress: Callable | None = None) -> int
¶
Pack loose objects into a packfile.
Consolidates loose git objects into a single packfile for better performance and disk usage. Implementations may also perform additional housekeeping (e.g. garbage collection) as a side effect.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress
|
Callable | None
|
Optional progress callback. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Number of objects packed. |
gc(*, progress: Callable | None = None) -> int
¶
Run garbage collection: clean up temporary files and pack loose objects.
Cleans up incomplete temporary pack files, then consolidates loose
objects into packfiles. This is a native implementation — it does
not require git to be installed.
Note: this does not prune unreachable objects. For full GC with
pruning, use git gc directly on the repository.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
progress
|
Callable | None
|
Optional progress callback. |
None
|
Returns:
| Type | Description |
|---|---|
int
|
Number of objects packed. |
backup(url: str, *, dry_run: bool = False, progress: Callable | None = None, refs: list[str] | dict[str, str] | None = None, format: str | None = None, squash: bool = False) -> MirrorDiff
¶
Push refs to url, or write a bundle file.
Without refs this is a full mirror: remote-only refs are deleted.
With refs only the specified refs are pushed (no deletes).
If url ends with .bundle (or format is "bundle"), a
portable bundle file is written instead of pushing to a remote.
refs may be a list of names (identity mapping) or a dict mapping source names to destination names for renaming on the remote side.
When squash is True and writing a bundle, each ref gets a
parentless commit with the same tree (stripping history).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Remote URL, local path, or |
required |
dry_run
|
bool
|
Compute diff without pushing. |
False
|
progress
|
Callable | None
|
Optional progress callback. |
None
|
refs
|
list[str] | dict[str, str] | None
|
Ref names to include (short or full), or a dict mapping
source to destination names. |
None
|
format
|
str | None
|
|
None
|
squash
|
bool
|
Strip history — each ref becomes a single parentless commit. Only supported for bundle output. |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
MirrorDiff
|
class: |
restore(url: str, *, dry_run: bool = False, progress: Callable | None = None, refs: list[str] | dict[str, str] | None = None, format: str | None = None) -> MirrorDiff
¶
Fetch refs from url, or import a bundle file.
Restore is additive: refs are added and updated but local-only
refs are never deleted. HEAD (the current branch pointer) is not
restored — use store.branches.current = "name" afterwards if
needed.
refs may be a list of names (identity mapping) or a dict mapping source names to destination names for renaming locally.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
url
|
str
|
Remote URL, local path, or |
required |
dry_run
|
bool
|
Compute diff without fetching. |
False
|
progress
|
Callable | None
|
Optional progress callback. |
None
|
refs
|
list[str] | dict[str, str] | None
|
Ref names to include (short or full), or a dict mapping
source to destination names. |
None
|
format
|
str | None
|
|
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
MirrorDiff
|
class: |
bundle_export(path: str, *, refs: list[str] | dict[str, str] | None = None, squash: bool = False, progress: Callable | None = None) -> None
¶
Export refs to a bundle file.
refs may be a list of names (identity mapping) or a dict mapping source names to destination names for renaming in the bundle.
When squash is True each ref in the bundle gets a parentless
commit whose tree matches the original tip, stripping all history.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Destination |
required |
refs
|
list[str] | dict[str, str] | None
|
Ref names to include (short or full), or a dict mapping
source to destination names. |
None
|
squash
|
bool
|
Strip history — each ref becomes a single parentless commit. |
False
|
progress
|
Callable | None
|
Optional progress callback. |
None
|
bundle_import(path: str, *, refs: list[str] | dict[str, str] | None = None, progress: Callable | None = None) -> None
¶
Import refs from a bundle file (additive — no deletes).
refs may be a list of names (identity mapping) or a dict mapping source names to destination names for renaming on import.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Source |
required |
refs
|
list[str] | dict[str, str] | None
|
Ref names to include (short or full), or a dict mapping
source to destination names. |
None
|
progress
|
Callable | None
|
Optional progress callback. |
None
|
Operations Overview¶
vost has four ways to move data. They differ in what they transfer and how much they replace at the destination.
| Operation | What it transfers | Destination behavior | Scope |
|---|---|---|---|
| copy | Individual files and directories | Additive — existing files are kept unless --delete is passed |
Selected paths |
| sync | A directory tree | Exact mirror — destination matches source, extras are deleted | One directory tree |
| archive | A snapshot as a single file | Exports to (or imports from) a .zip/.tar archive |
One branch or tag |
| backup / restore | The entire repository | All branches, tags, and history are pushed to (or fetched from) a remote git repo or bundle file | Whole repo |
copy and sync work with individual files between disk and repo (or within the repo). The difference is that copy is additive by default — it only adds or updates files — while sync makes the destination an exact replica of the source, deleting anything extra.
When --exclude patterns are used with either copy --delete or sync, excluded files in the destination are preserved (not deleted). This matches rsync's semantics: excluded files are invisible to the operation in both source and destination.
archive serializes one snapshot (branch, tag, or historical commit) into a single archive file, or imports one back. No git history is preserved — just the file tree at that point in time.
backup and restore operate at the git level. They push or fetch all refs (branches, tags) and their full commit history to another git repository. This is for disaster recovery and replication, not for working with individual files.
| I want to... | Use |
|---|---|
| Copy specific files into or out of the repo | copy_in / copy_out (cp) |
| Make a repo directory match a local directory | sync_in / sync_out (sync) |
| Export a snapshot as a zip/tar | archive_out / archive_in |
| Replicate the entire repo to another location | backup / restore |
| Create a portable bundle file | bundle_export / bundle_import |
FS (Snapshot)¶
vost.FS(gitstore: GitStore, commit_oid, ref_name: str | None = None, *, writable: bool | None = None)
¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
Snapshot Properties¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
writable: bool
property
¶
Whether this snapshot can be written to.
commit_hash: str
property
¶
The 40-character hex SHA of this snapshot's commit.
ref_name: str | None
property
¶
The branch or tag name, or None for detached snapshots.
tree_hash: str
property
¶
The 40-char hex SHA of the root tree.
message: str
property
¶
The commit message (trailing newline stripped).
time: datetime
property
¶
Timezone-aware commit timestamp.
author_name: str
property
¶
The commit author's name.
author_email: str
property
¶
The commit author's email address.
changes: ChangeReport | None
property
¶
Report of the operation that created this snapshot.
Querying Files¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
exists(path: str | os.PathLike[str]) -> bool
¶
Return True if path exists (file or directory).
is_dir(path: str | os.PathLike[str]) -> bool
¶
Return True if path is a directory (tree) in the repo.
file_type(path: str | os.PathLike[str]) -> FileType
¶
Return the :class:FileType of path.
Returns FileType.BLOB, FileType.EXECUTABLE,
FileType.LINK, or FileType.TREE.
Raises :exc:FileNotFoundError if the path does not exist.
size(path: str | os.PathLike[str]) -> int
¶
Return the size in bytes of the object at path.
Works without reading the full blob into memory.
Raises :exc:FileNotFoundError if the path does not exist.
object_hash(path: str | os.PathLike[str]) -> str
¶
Return the 40-character hex SHA of the object at path.
For files this is the blob SHA; for directories the tree SHA.
Raises :exc:FileNotFoundError if the path does not exist.
stat(path: str | os.PathLike[str] | None = None) -> StatResult
¶
Return a :class:StatResult for path (or root if None).
Combines file_type, size, oid, nlink, and mtime in a single call —
the hot path for FUSE getattr.
Reading Files¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
read(path: str | os.PathLike[str], *, offset: int = 0, size: int | None = None) -> bytes
¶
Read file contents as bytes.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
File path in the repo. |
required |
offset
|
int
|
Byte offset to start reading from. |
0
|
size
|
int | None
|
Maximum number of bytes to return ( |
None
|
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If path does not exist. |
IsADirectoryError
|
If path is a directory. |
read_text(path: str | os.PathLike[str], encoding: str = 'utf-8') -> str
¶
Read file contents as a string.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
File path in the repo. |
required |
encoding
|
str
|
Text encoding (default |
'utf-8'
|
read_by_hash(hash: str | bytes, *, offset: int = 0, size: int | None = None) -> bytes
¶
Read raw blob data by hash, bypassing tree lookup.
FUSE pattern: stat() → cache hash → read_by_hash(hash).
readlink(path: str | os.PathLike[str]) -> str
¶
Read the target of a symlink.
Listing & Search¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
ls(path: str | os.PathLike[str] | None = None) -> list[str]
¶
List entry names at path (or root if None).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str] | None
|
Directory path, or |
None
|
Raises:
| Type | Description |
|---|---|
NotADirectoryError
|
If path is a file. |
listdir(path: str | os.PathLike[str] | None = None) -> list[WalkEntry]
¶
List directory entries with name, oid, and mode.
Like :meth:ls but returns :class:WalkEntry objects so callers
get entry types (useful for FUSE readdir d_type).
walk(path: str | os.PathLike[str] | None = None) -> Iterator[tuple[str, list[str], list[WalkEntry]]]
¶
Walk the repo tree recursively, like :func:os.walk.
Yields (dirpath, dirnames, file_entries) tuples. Each file
entry is a :class:WalkEntry with name, oid, and mode.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str] | None
|
Subtree to walk, or |
None
|
Raises:
| Type | Description |
|---|---|
NotADirectoryError
|
If path is a file. |
glob(pattern: str) -> list[str]
¶
Expand a glob pattern against the repo tree.
Supports *, ?, and **. * and ? do not match
a leading . unless the pattern segment itself starts with ..
** matches zero or more directory levels, skipping directories
whose names start with ..
Returns a sorted, deduplicated list of matching paths (files and directories).
iglob(pattern: str) -> Iterator[str]
¶
Expand a glob pattern against the repo tree, yielding unique matches.
Like :meth:glob but returns an unordered iterator instead of a
sorted list. Useful when you only need to iterate once and don't
need sorted output.
A /./ pivot marker (rsync -R style) is preserved in the
output so that callers can reconstruct partial source paths.
Writing Files¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
write(path: str | os.PathLike[str], data: bytes, *, message: str | None = None, mode: FileType | int | None = None, parents: list[FS] | None = None) -> FS
¶
Write data to path and commit, returning a new :class:FS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
data
|
bytes
|
Raw bytes to write. |
required |
message
|
str | None
|
Commit message (auto-generated if |
None
|
mode
|
FileType | int | None
|
File mode override (e.g. |
None
|
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
StaleSnapshotError
|
If the branch has advanced since this snapshot. |
write_text(path: str | os.PathLike[str], text: str, *, encoding: str = 'utf-8', message: str | None = None, mode: FileType | int | None = None, parents: list[FS] | None = None) -> FS
¶
Write text to path and commit, returning a new :class:FS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
text
|
str
|
String content (encoded with encoding). |
required |
encoding
|
str
|
Text encoding (default |
'utf-8'
|
message
|
str | None
|
Commit message (auto-generated if |
None
|
mode
|
FileType | int | None
|
File mode override (e.g. |
None
|
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
StaleSnapshotError
|
If the branch has advanced since this snapshot. |
write_from_file(path: str | os.PathLike[str], local_path: str | os.PathLike[str], *, message: str | None = None, mode: FileType | int | None = None, parents: list[FS] | None = None) -> FS
¶
Write a local file into the repo and commit, returning a new :class:FS.
Executable permission is auto-detected from disk unless mode is set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
local_path
|
str | PathLike[str]
|
Path to the local file. |
required |
message
|
str | None
|
Commit message (auto-generated if |
None
|
mode
|
FileType | int | None
|
File mode override (e.g. |
None
|
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
StaleSnapshotError
|
If the branch has advanced since this snapshot. |
write_symlink(path: str | os.PathLike[str], target: str, *, message: str | None = None, parents: list[FS] | None = None) -> FS
¶
Create a symbolic link entry and commit, returning a new :class:FS.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Symlink path in the repo. |
required |
target
|
str
|
The symlink target string. |
required |
message
|
str | None
|
Commit message (auto-generated if |
None
|
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
StaleSnapshotError
|
If the branch has advanced since this snapshot. |
writer(path: str | os.PathLike[str], mode: str = 'wb')
¶
Return a writable file-like that commits on close.
"wb" accepts bytes; "w" accepts strings (UTF-8 encoded).
Example::
with fs.writer("output.bin") as f:
f.write(b"chunk1")
f.write(b"chunk2")
fs = f.fs # new snapshot
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
mode
|
str
|
|
'wb'
|
Raises:
| Type | Description |
|---|---|
PermissionError
|
If the snapshot is read-only. |
batch(message: str | None = None, operation: str | None = None, parents: list[FS] | None = None)
¶
Return a :class:Batch context manager for multiple writes in one commit.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str | None
|
Commit message (auto-generated if |
None
|
operation
|
str | None
|
Operation name for auto-generated messages. |
None
|
parents
|
list[FS] | None
|
Additional parent :class: |
None
|
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
Bulk Operations¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
copy_in(sources: str | list[str], dest: str, *, dry_run: bool = False, follow_symlinks: bool = False, message: str | None = None, mode: FileType | int | None = None, ignore_existing: bool = False, delete: bool = False, ignore_errors: bool = False, checksum: bool = True, exclude: ExcludeFilter | None = None, parents: list[FS] | None = None) -> FS
¶
Copy local files into the repo.
Sources must be literal paths; use :func:~vost.disk_glob to
expand patterns before calling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
str | list[str]
|
Local path(s). Trailing |
required |
dest
|
str
|
Destination path in the repo. |
required |
dry_run
|
bool
|
Preview only; returned FS has |
False
|
follow_symlinks
|
bool
|
Dereference symlinks on disk. |
False
|
message
|
str | None
|
Commit message (auto-generated if |
None
|
mode
|
FileType | int | None
|
Override file mode for all files. |
None
|
ignore_existing
|
bool
|
Skip files that already exist at dest. |
False
|
delete
|
bool
|
Remove repo files under dest not in source. Excluded files (via exclude) are preserved (rsync behavior). |
False
|
ignore_errors
|
bool
|
Collect errors instead of aborting. |
False
|
checksum
|
bool
|
Compare by content hash (default |
True
|
exclude
|
ExcludeFilter | None
|
Gitignore-style exclude filter. |
None
|
Returns:
| Type | Description |
|---|---|
FS
|
A new :class: |
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
copy_out(sources: str | list[str], dest: str, *, dry_run: bool = False, ignore_existing: bool = False, delete: bool = False, ignore_errors: bool = False, checksum: bool = True) -> FS
¶
Copy repo files to local disk.
Sources must be literal repo paths; use :meth:glob to expand
patterns before calling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
str | list[str]
|
Repo path(s). Trailing |
required |
dest
|
str
|
Local destination directory. |
required |
dry_run
|
bool
|
Preview only; returned FS has |
False
|
ignore_existing
|
bool
|
Skip files that already exist at dest. |
False
|
delete
|
bool
|
Remove local files under dest not in source. |
False
|
ignore_errors
|
bool
|
Collect errors instead of aborting. |
False
|
checksum
|
bool
|
Compare by content hash (default |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
This |
FS
|
class: |
sync_in(local_path: str, repo_path: str, *, dry_run: bool = False, message: str | None = None, ignore_errors: bool = False, checksum: bool = True, exclude: ExcludeFilter | None = None, parents: list[FS] | None = None) -> FS
¶
Make repo_path identical to local_path (including deletes).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
local_path
|
str
|
Local directory to sync from. |
required |
repo_path
|
str
|
Repo directory to sync to. |
required |
dry_run
|
bool
|
Preview only; returned FS has |
False
|
message
|
str | None
|
Commit message (auto-generated if |
None
|
ignore_errors
|
bool
|
Collect errors instead of aborting. |
False
|
checksum
|
bool
|
Compare by content hash (default |
True
|
exclude
|
ExcludeFilter | None
|
Gitignore-style exclude filter. |
None
|
Returns:
| Type | Description |
|---|---|
FS
|
A new :class: |
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
sync_out(repo_path: str, local_path: str, *, dry_run: bool = False, ignore_errors: bool = False, checksum: bool = True) -> FS
¶
Make local_path identical to repo_path (including deletes).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
repo_path
|
str
|
Repo directory to sync from. |
required |
local_path
|
str
|
Local directory to sync to. |
required |
dry_run
|
bool
|
Preview only; returned FS has |
False
|
ignore_errors
|
bool
|
Collect errors instead of aborting. |
False
|
checksum
|
bool
|
Compare by content hash (default |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
This |
FS
|
class: |
remove(sources: str | list[str], *, recursive: bool = False, dry_run: bool = False, message: str | None = None, parents: list[FS] | None = None) -> FS
¶
Remove files from the repo.
Sources must be literal paths; use :meth:glob to expand patterns
before calling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
str | list[str]
|
Repo path(s) to remove. |
required |
recursive
|
bool
|
Allow removing directories. |
False
|
dry_run
|
bool
|
Preview only; returned FS has |
False
|
message
|
str | None
|
Commit message (auto-generated if |
None
|
Returns:
| Type | Description |
|---|---|
FS
|
A new :class: |
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
FileNotFoundError
|
If no source paths match. |
move(sources: str | list[str], dest: str, *, recursive: bool = False, dry_run: bool = False, message: str | None = None, parents: list[FS] | None = None) -> FS
¶
Move or rename files within the repo.
Sources must be literal paths; use :meth:glob to expand patterns
before calling.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sources
|
str | list[str]
|
Repo path(s) to move. |
required |
dest
|
str
|
Destination path in the repo. |
required |
recursive
|
bool
|
Allow moving directories. |
False
|
dry_run
|
bool
|
Preview only; returned FS has |
False
|
message
|
str | None
|
Commit message (auto-generated if |
None
|
Returns:
| Type | Description |
|---|---|
FS
|
A new :class: |
Raises:
| Type | Description |
|---|---|
PermissionError
|
If this snapshot is read-only. |
copy_from_ref(source: FS | str, sources: str | list[str] = '', dest: str = '', *, delete: bool = False, dry_run: bool = False, message: str | None = None, parents: list[FS] | None = None) -> FS
¶
Copy files from source into this branch in a single atomic commit.
Follows the same rsync trailing-slash conventions as
copy_in/copy_out:
"config"→ directory mode — copiesconfig/asconfig/under dest."config/"→ contents mode — pours the contents ofconfig/into dest."file.txt"→ file mode — copies the single file into dest.""or"/"→ root contents mode — copies everything.
Since both snapshots share the same object store, blobs are referenced by OID — no data is read into memory regardless of file size.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
FS | str
|
Any FS (branch, tag, detached commit), or a branch/tag name string that will be resolved to an FS. Read-only; not modified. |
required |
sources
|
str | list[str]
|
Source path(s) in source. Accepts a single string or a
list of strings. Defaults to |
''
|
dest
|
str
|
Destination path in this branch. Defaults to |
''
|
delete
|
bool
|
Remove dest files under the target that aren't in source. |
False
|
dry_run
|
bool
|
Compute changes but don't commit. Returned FS has |
False
|
message
|
str | None
|
Commit message (auto-generated if |
None
|
Returns:
| Type | Description |
|---|---|
FS
|
A new :class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If source belongs to a different repo or cannot be resolved. |
FileNotFoundError
|
If a source path does not exist. |
PermissionError
|
If this FS is read-only. |
apply(writes: dict[str, WriteEntry | bytes | str | Path] | None = None, removes: str | list[str] | set[str] | None = None, *, message: str | None = None, operation: str | None = None, parents: list[FS] | None = None) -> FS
¶
Apply multiple writes and removes in a single atomic commit.
writes maps repo paths to content. Values may be:
bytes— raw blob datastr— UTF-8 text (encoded automatically)- :class:
~pathlib.Path— read from local file (mode auto-detected) - :class:
WriteEntry— full control over source, mode, and symlinks
removes lists repo paths to delete (str, list, or set).
Returns a new :class:FS snapshot with the changes committed.
History & Navigation¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
parent: FS | None
property
¶
The parent snapshot, or None for the initial commit.
back(n: int = 1) -> FS
¶
Return the FS at the n-th ancestor commit.
Raises ValueError if n < 0 or history is too short.
log(path: str | os.PathLike[str] | None = None, *, match: str | None = None, before: datetime | None = None) -> Iterator[FS]
¶
Walk the commit history, yielding ancestor :class:FS snapshots.
All filters are optional and combine with AND.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str] | None
|
Only yield commits that changed this file. |
None
|
match
|
str | None
|
Message pattern ( |
None
|
before
|
datetime | None
|
Only yield commits on or before this time. |
None
|
undo(steps: int = 1) -> FS
¶
Move branch back N commits.
Walks back through parent commits and updates the branch pointer. Automatically writes a reflog entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
steps
|
int
|
Number of commits to undo (default 1) |
1
|
Returns:
| Type | Description |
|---|---|
FS
|
New FS snapshot at the parent commit |
Raises:
| Type | Description |
|---|---|
PermissionError
|
If called on read-only snapshot (tag) |
ValueError
|
If not enough history exists |
Example
fs = repo.branches["main"] fs = fs.undo() # Go back 1 commit fs = fs.undo(3) # Go back 3 commits
redo(steps: int = 1) -> FS
¶
Move branch forward N steps using reflog.
Reads the reflog to find where the branch was before the last N movements. This can resurrect "orphaned" commits after undo.
The reflog tracks all branch movements chronologically. Each redo step moves back one entry in the reflog (backwards in time through the log, but forward in commit history).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
steps
|
int
|
Number of reflog entries to go back (default 1) |
1
|
Returns:
| Type | Description |
|---|---|
FS
|
New FS snapshot at the target position |
Raises:
| Type | Description |
|---|---|
PermissionError
|
If called on read-only snapshot (tag) |
ValueError
|
If not enough redo history exists |
Example
fs = fs.undo(2) # Creates 1 reflog entry moving back 2 commits fs = fs.redo() # Go back 1 reflog entry (to before the undo)
Lifecycle¶
An immutable snapshot of a committed tree.
Read-only when writable is False (tag snapshot).
Writable when writable is True — writes auto-commit and return a new FS.
close() -> None
¶
Release cached resources (ObjectSizer file descriptors).
Batch¶
vost.Batch(fs: FS, message: str | None = None, operation: str | None = None, parents: list[FS] | None = None)
¶
Accumulates writes and removes, committing them in a single atomic commit.
Use as a context manager or call :meth:commit explicitly. Nothing is
committed if an exception occurs inside the with block.
Attributes:
| Name | Type | Description |
|---|---|---|
fs |
FS | None
|
The resulting :class: |
write(path: str | os.PathLike[str], data: bytes, *, mode: FileType | int | None = None) -> None
¶
Stage a file write.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
data
|
bytes
|
Raw bytes to write. |
required |
mode
|
FileType | int | None
|
File mode override (e.g. |
None
|
write_from_file(path: str | os.PathLike[str], local_path: str | os.PathLike[str], *, mode: FileType | int | None = None) -> None
¶
Stage a write from a local file.
Executable permission is auto-detected from disk unless mode is set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
local_path
|
str | PathLike[str]
|
Path to the local file. |
required |
mode
|
FileType | int | None
|
File mode override (e.g. |
None
|
write_text(path: str | os.PathLike[str], text: str, *, encoding: str = 'utf-8', mode: FileType | int | None = None) -> None
¶
Stage a text write (convenience wrapper around :meth:write).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
text
|
str
|
String content (encoded with encoding). |
required |
encoding
|
str
|
Text encoding (default |
'utf-8'
|
mode
|
FileType | int | None
|
File mode override (e.g. |
None
|
write_symlink(path: str | os.PathLike[str], target: str) -> None
¶
Stage a symbolic link entry.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Symlink path in the repo. |
required |
target
|
str
|
The symlink target string. |
required |
remove(path: str | os.PathLike[str]) -> None
¶
Stage a file removal.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Path to remove from the repo. |
required |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If path does not exist in the repo or pending writes. |
IsADirectoryError
|
If path is a directory. |
writer(path: str | os.PathLike[str], mode: str = 'wb')
¶
Return a writable file-like that stages to the batch on close.
"wb" accepts bytes; "w" accepts strings (UTF-8 encoded).
Example::
with fs.batch() as b:
with b.writer("log.txt", "w") as f:
f.write("line 1\n")
f.write("line 2\n")
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str | PathLike[str]
|
Destination path in the repo. |
required |
mode
|
str
|
|
'wb'
|
commit() -> FS
¶
Explicitly commit the batch, like __exit__ with no exception.
After calling this the batch is closed and no further writes are
allowed. Returns the resulting FS.
Branches & Tags¶
vost.RefDict(store: GitStore, prefix: str)
¶
Bases: MutableMapping
Dict-like access to branches or tags.
store.branches and store.tags are both RefDict instances.
Supports [], del, in, len, and iteration.
current: FS | None
property
writable
¶
The FS for the repository's current (HEAD) branch, or None if HEAD is dangling.
Only valid for branches; raises ValueError for tags.
current_name: str | None
property
¶
The repository's current (HEAD) branch name, or None if HEAD is dangling.
Only valid for branches; raises ValueError for tags.
Cheap — does not construct an FS object.
set(name: str, fs: FS) -> FS
¶
Set branch to FS snapshot and return writable FS bound to it.
This is a convenience method that combines setting and getting:
fs_new = repo.branches.set('feature', fs)
Is equivalent to:
repo.branches['feature'] = fs
fs_new = repo.branches['feature']
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Branch name |
required |
fs
|
FS
|
FS snapshot to set (can be read-only) |
required |
Returns:
| Type | Description |
|---|---|
FS
|
New writable FS bound to the branch |
Example
fs_wow = repo.branches.set('wow', fs_main) fs_wow.ref_name # 'wow' (not 'main')
reflog(name: str) -> list[ReflogEntry]
¶
Read reflog entries for a branch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Branch name (e.g., "main") |
required |
Returns:
| Type | Description |
|---|---|
list[ReflogEntry]
|
List of :class: |
Raises:
| Type | Description |
|---|---|
KeyError
|
If branch doesn't exist |
FileNotFoundError
|
If no reflog exists |
Example
entries = repo.branches.reflog("main") for e in entries: ... print(f"{e.message}: {e.new_sha[:7]}")
vost.Signature(name: str, email: str)
dataclass
¶
Author/committer identity used for commits.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Author name (e.g. |
email |
str
|
Author email (e.g. |
vost.ReflogEntry(old_sha: str, new_sha: str, committer: str, timestamp: float, message: str)
dataclass
¶
A single reflog entry recording a branch movement.
Attributes:
| Name | Type | Description |
|---|---|---|
old_sha |
str
|
Previous 40-char hex commit SHA. |
new_sha |
str
|
New 40-char hex commit SHA. |
committer |
str
|
Identity string of the committer. |
timestamp |
float
|
POSIX epoch seconds of the entry. |
message |
str
|
Reflog message (e.g. |
Notes¶
vost.NoteDict(store: GitStore)
¶
Outer container for git notes namespaces on a :class:GitStore.
store.notes.commits → default namespace (refs/notes/commits).
store.notes['reviews'] → custom namespace.
commits: NoteNamespace
property
¶
The default refs/notes/commits namespace.
vost.NoteNamespace(store: GitStore, namespace: str)
¶
Bases: MutableMapping
One git notes namespace, backed by refs/notes/<name>.
Maps commit hashes to UTF-8 note text. Keys can be 40-char hex
commit hashes or ref names (branch/tag), which are resolved to
the tip commit hash.
Supports [], del, in, len, and iteration.
vost.NotesBatch(ns: NoteNamespace)
¶
Collects note writes/deletes and applies them in one commit on exit.
Usage::
with store.notes.commits.batch() as b:
b[hash1] = "note 1"
b[hash2] = "note 2"
del b[hash3]
# single commit
Backup & Restore¶
See GitStore.backup() and GitStore.restore().
For direct bundle file operations without the full backup/restore logic, see GitStore.bundle_export() and GitStore.bundle_import().
Exclude Filter¶
vost.ExcludeFilter(*, patterns: Sequence[str] | None = None, exclude_from: str | None = None, gitignore: bool = False)
¶
Gitignore-style exclude filter for disk-to-repo operations.
Combines --exclude patterns, --exclude-from file, and automatic
.gitignore loading into a single predicate.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
patterns
|
Sequence[str] | None
|
Gitignore-style patterns to exclude. |
None
|
exclude_from
|
str | None
|
Path to a file containing exclude patterns. |
None
|
gitignore
|
bool
|
Load |
False
|
active: bool
property
¶
True if any filtering is configured.
is_excluded(rel_path: str, *, is_dir: bool = False) -> bool
¶
Check against base patterns only (for post-filtering).
enter_directory(abs_dir: Path, rel_dir: str) -> None
¶
Load .gitignore from abs_dir if gitignore mode is on.
is_excluded_in_walk(rel_path: str, *, is_dir: bool = False) -> bool
¶
Check base patterns + loaded .gitignore hierarchy.
Called during os.walk() after enter_directory has been
invoked for every ancestor.
Exceptions¶
vost.StaleSnapshotError
¶
Bases: Exception
Raised when a write is attempted on a snapshot whose branch has advanced.
Re-fetch the branch via store.branches["name"] and retry, or use
:func:~vost.retry_write for automatic retry with backoff.
Utility Functions¶
vost.retry_write(store: GitStore, branch: str, path: str | os.PathLike[str], data: bytes, *, message: str | None = None, mode: FileType | int | None = None, retries: int = 5, parents: list[FS] | None = None) -> FS
¶
Write data to a branch with automatic retry on concurrent modification.
Re-fetches the branch FS on each attempt. Uses exponential backoff with jitter (base 10ms, factor 2x, cap 200ms) to avoid thundering-herd.
Raises StaleSnapshotError if all attempts are exhausted.
Raises KeyError if the branch does not exist.
vost.resolve_credentials(url: str) -> str
¶
Inject credentials into an HTTPS URL if available.
Tries git credential fill first (works with any configured helper:
osxkeychain, wincred, libsecret, gh auth setup-git, etc.). Falls
back to gh auth token for GitHub hosts. Non-HTTPS URLs and URLs
that already contain credentials are returned unchanged.
vost.disk_glob(pattern: str) -> list[str]
¶
Expand a glob pattern against the local filesystem.
Same dotfile rules as the repo-side fs.glob().
Returns a sorted list of matching paths.
Data Types¶
Types returned by API methods. Most are opaque — you rarely need to construct or import them directly.
vost.StatResult(mode: int, file_type: FileType, size: int, hash: str, nlink: int, mtime: float)
dataclass
¶
POSIX-like stat result for a vost path.
Attributes:
| Name | Type | Description |
|---|---|---|
mode |
int
|
Raw git filemode (e.g. |
file_type |
FileType
|
:class: |
size |
int
|
Object size in bytes (0 for directories). |
hash |
str
|
40-char hex SHA of the object (inode proxy). |
nlink |
int
|
1 for files/symlinks, |
mtime |
float
|
Commit timestamp as POSIX epoch seconds. |
vost.WalkEntry
¶
Bases: NamedTuple
A file entry yielded by :meth:~vost.FS.walk and :meth:~vost.FS.listdir.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Entry name (file or directory basename). |
oid |
bytes
|
Raw object ID (bytes). |
mode |
int
|
Git filemode integer (e.g. |
file_type
property
¶
Return the :class:~vost.copy._types.FileType for this entry.
vost.FileType
¶
vost.FileEntry(path: str, type: FileType, src: str | None = None)
dataclass
¶
A file path with type information, used in :class:ChangeReport lists.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
str
|
Relative path (repo-style forward slashes). |
type |
FileType
|
:class: |
src |
str | None
|
Source path (local file, repo path, or |
from_mode(path: str, mode: int, src: str | None = None) -> FileEntry
classmethod
¶
Create FileEntry from path and git filemode.
vost.BlobOid
¶
Bases: bytes
A blob SHA used as a marker in write dicts to avoid re-hashing.
Subclass of :class:bytes. When a value in a write dict is a
BlobOid, the tree builder uses it directly instead of calling
create_blob.
vost.WriteEntry(data: bytes | str | Path | None = None, mode: FileType | int | None = None, target: str | None = None)
dataclass
¶
Describes a single file write for :meth:FS.apply.
Exactly one of data or target must be provided.
data may be bytes, str (UTF-8 text), or a :class:~pathlib.Path
to a local file. mode optionally overrides the filemode
(e.g. FileType.EXECUTABLE).
target creates a symbolic link entry; mode is not allowed with it.
vost.ChangeReport(add: list[FileEntry] = list(), update: list[FileEntry] = list(), delete: list[FileEntry] = list(), errors: list[ChangeError] = list(), warnings: list[ChangeError] = list())
dataclass
¶
Result of a copy, sync, move, or remove operation.
Available on the :attr:~vost.FS.changes property of the
resulting snapshot (both dry-run and real).
Attributes:
| Name | Type | Description |
|---|---|---|
add |
list[FileEntry]
|
Files added. |
update |
list[FileEntry]
|
Files updated. |
delete |
list[FileEntry]
|
Files deleted. |
errors |
list[ChangeError]
|
Per-file errors (populated when |
warnings |
list[ChangeError]
|
Non-fatal warnings. |
vost.ChangeAction(path: str, action: ChangeActionKind)
dataclass
¶
A single add/update/delete action in a :class:ChangeReport.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
str
|
Relative path (repo-style forward slashes). |
action |
ChangeActionKind
|
:class: |
vost.ChangeActionKind
¶
Bases: str, Enum
Kind of change action: ADD, UPDATE, or DELETE.
vost.ChangeError(path: str, error: str)
dataclass
¶
A file that failed during an operation.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
str
|
The path that caused the error. |
error |
str
|
Human-readable error message. |
vost.MirrorDiff(add: list[RefChange] = list(), update: list[RefChange] = list(), delete: list[RefChange] = list())
dataclass
¶
vost.RefChange(ref: str, old_target: str | None = None, new_target: str | None = None)
dataclass
¶
A single ref change in a :class:MirrorDiff.
Attributes:
| Name | Type | Description |
|---|---|---|
ref |
str
|
Full ref name (e.g. |
old_target |
str | None
|
Previous 40-char hex SHA, or |
new_target |
str | None
|
New 40-char hex SHA, or |