Clojure binding to rift — copy-on-write development workspaces, a faster
alternative to git worktree — via the native librift_ffi shared library
loaded in-process through the JDK Foreign Function & Memory API
(java.lang.foreign, stable since JDK 22).
The native ABI is exactly two C symbols, JSON in / JSON out:
char* rift_ffi_call(const char* json_request) ;; heap-allocated reply void rift_ffi_free(char* reply)
A request is {"command" "create" ...}; a reply is either
{"status" "ok" "value" ...} or
{"status" "error" "error" {"code" .. "message" .. "path" ..}}.
We bundle the prebuilt library for every supported platform under
resources/prebuilds/<os>-<arch>/, extract the matching one to a temp file
at first use (you cannot dlopen from inside a jar), open it, and bind the
two symbols. The library is mapped for the lifetime of the process.
Supported platforms: darwin-arm64, darwin-x64, linux-x64, linux-arm64.
REQUIRES the JVM flag --enable-native-access=ALL-UNNAMED; without it the
first native call prints a restricted-method warning (and on a future JDK
default of --illegal-native-access=deny would fail outright).
Clojure binding to rift — copy-on-write development workspaces, a faster
alternative to `git worktree` — via the native `librift_ffi` shared library
loaded in-process through the JDK Foreign Function & Memory API
(`java.lang.foreign`, stable since JDK 22).
The native ABI is exactly two C symbols, JSON in / JSON out:
char* rift_ffi_call(const char* json_request) ;; heap-allocated reply
void rift_ffi_free(char* reply)
A request is `{"command" "create" ...}`; a reply is either
`{"status" "ok" "value" ...}` or
`{"status" "error" "error" {"code" .. "message" .. "path" ..}}`.
We bundle the prebuilt library for every supported platform under
`resources/prebuilds/<os>-<arch>/`, extract the matching one to a temp file
at first use (you cannot `dlopen` from inside a jar), open it, and bind the
two symbols. The library is mapped for the lifetime of the process.
Supported platforms: darwin-arm64, darwin-x64, linux-x64, linux-arm64.
REQUIRES the JVM flag `--enable-native-access=ALL-UNNAMED`; without it the
first native call prints a restricted-method warning (and on a future JDK
default of `--illegal-native-access=deny` would fail outright).Override for the rift registry (SQLite) path used when a call omits
:database. nil ⇒ fall back to the platform default (default-database),
which is always resolved and passed explicitly — so the default is honoured
on every platform, never left to chance.
Precedence, highest first:
:database on the call,(with-database path …) scope,set-default-database!),(default-database)).Override for the rift registry (SQLite) path used when a call omits `:database`. `nil` ⇒ fall back to the platform default (`default-database`), which is always resolved and passed explicitly — so the default is honoured on every platform, never left to chance. Precedence, highest first: 1. an explicit `:database` on the call, 2. a `(with-database path …)` scope, 3. this var's root value (set once via `set-default-database!`), 4. the platform default (`(default-database)`).
(ancestors)(ancestors {:keys [of database]})List ancestor workspaces of :of (default: current dir), nearest first.
Returns a vector of paths. Options: :of, :database.
List ancestor workspaces of `:of` (default: current dir), nearest first. Returns a vector of paths. Options: `:of`, `:database`.
(create)(create {:keys [from name into database]})Create a copy-on-write workspace from :from (default: current dir) and
return the new workspace path (string). When :from is a git repo the new
workspace has a detached HEAD with index + working-tree state retained.
Options: :from, :name, :into (parent storage dir), :database.
Create a copy-on-write workspace from `:from` (default: current dir) and return the new workspace path (string). When `:from` is a git repo the new workspace has a detached HEAD with index + working-tree state retained. Options: `:from`, `:name`, `:into` (parent storage dir), `:database`.
(default-database)The platform-default rift registry (SQLite) path — the same one rift would
choose when no :database is given (dirs::data_local_dir()/rift/rift.sqlite):
The platform-default rift registry (SQLite) path — the same one rift would choose when no `:database` is given (`dirs::data_local_dir()/rift/rift.sqlite`): - macOS: ~/Library/Application Support/rift/rift.sqlite - Windows: %LOCALAPPDATA%\rift\rift.sqlite - Linux: $XDG_DATA_HOME/rift/rift.sqlite (else ~/.local/share/…)
(gc)(gc {:keys [database]})Physically delete trashed storage and prune missing registry entries.
Returns a vector of collected paths. Options: :database.
Physically delete trashed storage and prune missing registry entries. Returns a vector of collected paths. Options: `:database`.
(init)(init {:keys [at database]})Initialize / register a rift root at :at (default: current dir). On Linux
this converts an ordinary btrfs directory into a subvolume; on macOS it
registers the source directory for APFS clonefile. Returns nil.
Options: :at, :database (defaults to *database*).
Initialize / register a rift root at `:at` (default: current dir). On Linux this converts an ordinary btrfs directory into a subvolume; on macOS it registers the source directory for APFS clonefile. Returns nil. Options: `:at`, `:database` (defaults to `*database*`).
(list)(list {:keys [of database]})List direct active child workspaces of :of (default: current dir).
Returns a vector of paths. Options: :of, :database.
List direct active child workspaces of `:of` (default: current dir). Returns a vector of paths. Options: `:of`, `:database`.
(remove!)(remove! {:keys [at all database]})Remove a created workspace at :at (default: current dir). With :all true
removes the whole created subtree and returns a vector of removed paths;
otherwise returns nil. Removed storage is trashed adjacent to the root until
gc deletes it.
Options: :at, :all, :database.
Remove a created workspace at `:at` (default: current dir). With `:all true` removes the whole created subtree and returns a vector of removed paths; otherwise returns nil. Removed storage is trashed adjacent to the root until `gc` deletes it. Options: `:at`, `:all`, `:database`.
(set-default-database! path)Set the process-wide default registry path (the root value of *database*),
so every later call uses it without passing :database. Pass nil to
revert to rift's built-in default. Returns the path.
Set the process-wide default registry path (the root value of `*database*`), so every later call uses it without passing `:database`. Pass `nil` to revert to rift's built-in default. Returns the path.
(with-database path & body)Evaluate body with *database* bound to path (a scoped default that
wins over set-default-database! but not over an explicit per-call
:database).
Evaluate `body` with `*database*` bound to `path` (a scoped default that wins over `set-default-database!` but not over an explicit per-call `:database`).
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |