Library
Module
Module type
Parameter
Class
Class type
Store for the log. All store related operations like branching, cloning, merging, etc are done through this module.
Irmin stores are tree-like read-write stores with extended capabilities. They allow an application (or a collection of applications) to work with multiple local states, which can be forked and merged programmatically, without having to rely on a global state. In a way very similar to version control systems, Irmin local states are called branches.
There are two kinds of store in Irmin: the ones based on persistent named branches and the ones based temporary detached heads. These exist relative to a local, larger (and shared) store, and have some (shared) contents. This is exactly the same as usual version control systems, that the informed user can see as an implicit purely functional data-structure.
The type for key
steps.
The type for store keys. A key is a sequence of step
s.
Type for persistent branch names. Branches usually share a common global namespace and it's the user's responsibility to avoid name clashes.
The type for errors associated with functions computing least common ancestors
The type for errors for fast_forward
.
module Repo : sig ... end
Repositories.
empty repo
is a temporary, empty store. Becomes a normal temporary store after the first update.
master repo
is a persistent store based on r
's master branch. This operation is cheap, can be repeated multiple times.
of_branch r name
is a persistent store based on the branch name
. Similar to master
, but use name
instead Branch.S.master
.
of_commit c
is a temporary store, based on the commit c
.
Temporary stores do not have stable names: instead they can be addressed using the hash of the current commit. Temporary stores are similar to Git's detached heads. In a temporary store, all the operations are performed relative to the current head and update operations can modify the current head: the current stores's head will automatically become the new head obtained after performing the update.
tree t
is t
's current tree. Contents is not allowed at the root of the tree.
module Status : sig ... end
module Head : sig ... end
Managing the store's heads.
module Hash : Irmin.Hash.S with type t = hash
Object hashes.
module Commit : sig ... end
Commit
defines immutable objects to describe store updates.
module Contents : sig ... end
Contents
provides base functions for the store's contents.
module Tree : sig ... end
Managing store's trees.
kind
is Tree.kind
applied to t
's root tree.
mem_tree t
is Tree.mem_tree
applied to t
's root tree.
find_all t
is Tree.find_all
applied to t
's root tree.
get_all t
is Tree.get_all
applied on t
's root tree.
find_tree t
is Tree.find_tree
applied to t
's root tree.
get_tree t k
is Tree.get_tree
applied to t
's root tree.
The type for write errors.
v
instead of the one we were waiting for.val set :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
contents ->
(unit, write_error) Stdlib.result Lwt.t
set t k ~info v
sets k
to the value v
in t
. Discard any previous results but ensure that no operation is lost in the history.
This function always uses Metadata.default
as metadata. Use set_tree
with `Contents (c, m)
for different ones.
The result is Error `Too_many_retries
if the concurrent operations do not allow the operation to commit to the underlying storage layer (livelock).
val set_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
contents ->
unit Lwt.t
set_exn
is like set
but raise Failure _
instead of using a result type.
val set_tree :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
tree ->
(unit, write_error) Stdlib.result Lwt.t
set_tree
is like set
but for trees.
val set_tree_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
tree ->
unit Lwt.t
set_tree
is like set_exn
but for trees.
val remove :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
(unit, write_error) Stdlib.result Lwt.t
remove t ~info k
remove any bindings to k
in t
.
The result is Error `Too_many_retries
if the concurrent operations do not allow the operation to commit to the underlying storage layer (livelock).
val remove_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
unit Lwt.t
remove_exn
is like remove
but raise Failure _
instead of a using result type.
val test_and_set :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
test:contents option ->
set:contents option ->
(unit, write_error) Stdlib.result Lwt.t
test_and_set ~test ~set
is like set
but it atomically checks that the tree is test
before modifying it to set
.
This function always uses Metadata.default
as metadata. Use test_and_set_tree
with `Contents (c, m)
for different ones.
The result is Error (`Test t)
if the current tree is t
instead of test
.
The result is Error `Too_many_retries
if the concurrent operations do not allow the operation to commit to the underlying storage layer (livelock).
val test_and_set_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
test:contents option ->
set:contents option ->
unit Lwt.t
test_and_set_exn
is like test_and_set
but raise Failure _
instead of using a result type.
val test_and_set_tree :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
test:tree option ->
set:tree option ->
(unit, write_error) Stdlib.result Lwt.t
test_and_set_tree
is like test_and_set
but for trees.
val test_and_set_tree_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
t ->
key ->
test:tree option ->
set:tree option ->
unit Lwt.t
test_and_set_tree_exn
is like test_and_set_exn
but for trees.
val merge :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
old:contents option ->
t ->
key ->
contents option ->
(unit, write_error) Stdlib.result Lwt.t
merge ~old
is like set
but merge the current tree and the new tree using old
as ancestor in case of conflicts.
This function always uses Metadata.default
as metadata. Use merge_tree
with `Contents (c, m)
for different ones.
The result is Error (`Conflict c)
if the merge failed with the conflict c
.
The result is Error `Too_many_retries
if the concurrent operations do not allow the operation to commit to the underlying storage layer (livelock).
val merge_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
old:contents option ->
t ->
key ->
contents option ->
unit Lwt.t
merge_exn
is like merge
but raise Failure _
instead of using a result type.
val merge_tree :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
old:tree option ->
t ->
key ->
tree option ->
(unit, write_error) Stdlib.result Lwt.t
merge_tree
is like merge_tree
but for trees.
val merge_tree_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
info:Irmin.Info.f ->
old:tree option ->
t ->
key ->
tree option ->
unit Lwt.t
merge_tree
is like merge_tree
but for trees.
val with_tree :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
?strategy:[ `Set | `Test_and_set | `Merge ] ->
info:Irmin.Info.f ->
t ->
key ->
(tree option -> tree option Lwt.t) ->
(unit, write_error) Stdlib.result Lwt.t
with_tree t k ~info f
replaces atomically the subtree v
under k
in the store t
by the contents of the tree f v
, using the commit info info ()
.
If v = f v
and allow_empty
is unset (default) then, the operation is a no-op.
If v != f v
and no other changes happen concurrently, f v
becomes the new subtree under k
. If other changes happen concurrently to that operations, the semantics depend on the value of strategy
:
strategy = `Set
, use set
and discard any concurrent updates to k
.strategy = `Test_and_set
(default), use test_and_set
and ensure that no concurrent operations are updating k
.strategy = `Merge
, use merge
and ensure that concurrent updates and merged with the values present at the beginning of the transaction.Note: Irmin transactions provides snapshot isolation guarantees: reads and writes are isolated in every transaction, but only write conflicts are visible on commit.
val with_tree_exn :
?retries:int ->
?allow_empty:bool ->
?parents:commit list ->
?strategy:[ `Set | `Test_and_set | `Merge ] ->
info:Irmin.Info.f ->
t ->
key ->
(tree option -> tree option Lwt.t) ->
unit Lwt.t
with_tree_exn
is like with_tree
but raise Failure _
instead of using a return type.
clone ~src ~dst
makes dst
points to Head.get src
. dst
is created if needed. Remove the current contents en dst
if src
is empty
.
val watch :
t ->
?init:commit ->
(commit Irmin.Diff.t -> unit Lwt.t) ->
watch Lwt.t
watch t f
calls f
every time the contents of t
's head is updated.
Note: even if f
might skip some head updates, it will never be called concurrently: all consecutive calls to f
are done in sequence, so we ensure that the previous one ended before calling the next one.
val watch_key :
t ->
key ->
?init:commit ->
((commit * tree) Irmin.Diff.t -> unit Lwt.t) ->
watch Lwt.t
watch_key t key f
calls f
every time the key
's value is added, removed or updated. If the current branch is deleted, no signal is sent to the watcher.
val unwatch : watch -> unit Lwt.t
unwatch w
disable w
. Return once the w
is fully disabled.
type 'a merge =
info:Irmin.Info.f ->
?max_depth:int ->
?n:int ->
'a ->
(unit, Irmin.Merge.conflict) Stdlib.result Lwt.t
The type for merge functions.
merge_into ~into i t
merges t
's current branch into x
's current branch using the info i
. After that operation, the two stores are still independent. Similar to git merge <branch>
.
lca ?max_depth ?n msg t1 t2
returns the collection of least common ancestors between the heads of t1
and t2
branches.
max_depth
is the maximum depth of the exploration (default is max_int
). Return Error `Max_depth_reached
if this depth is exceeded.n
is the maximum expected number of lcas. Stop the exploration as soon as n
lcas are found. Return Error `Too_many_lcas
if more lcas
are found.val lcas_with_branch :
t ->
?max_depth:int ->
?n:int ->
branch ->
(commit list, lca_error) Stdlib.result Lwt.t
Same as lcas
but takes a branch ID as argument.
val lcas_with_commit :
t ->
?max_depth:int ->
?n:int ->
commit ->
(commit list, lca_error) Stdlib.result Lwt.t
Same as lcas
but takes a commit ID as argument.
module History : Graph.Sig.P with type V.t = commit
An history is a DAG of heads.
history ?depth ?min ?max t
is a view of the history of the store t
, of depth at most depth
, starting from the t
's head (or from max
if the head is not set) and stopping at min
if specified.
last_modified ?number c k
is the list of the last number
commits that modified key
, in ascending order of date. depth
is the maximum depth to be explored in the commit graph, if any. Default value for number
is 1.
module Branch : sig ... end
Manipulate branches.
Key
provides base functions for the stores's paths.
module Metadata : sig ... end
Metadata
provides base functions for node metadata.
val step_t : step Irmin.Type.t
step_t
is the value type for step
.
val key_t : key Irmin.Type.t
key_t
is the value type for key
.
val metadata_t : metadata Irmin.Type.t
metadata_t
is the value type for metadata
.
val contents_t : contents Irmin.Type.t
contents_t
is the value type for contents
.
val node_t : node Irmin.Type.t
node_t
is the value type for node
.
val tree_t : tree Irmin.Type.t
tree_t
is the value type for tree
.
val commit_t : repo -> commit Irmin.Type.t
commit_t r
is the value type for commit
.
val branch_t : branch Irmin.Type.t
branch_t
is the value type for branch
.
val slice_t : slice Irmin.Type.t
slice_t
is the value type for slice
.
val kind_t : [ `Contents | `Node ] Irmin.Type.t
kind_t
is the value type for values returned by kind
.
val lca_error_t : lca_error Irmin.Type.t
lca_error_t
is the value type for lca_error
.
val ff_error_t : ff_error Irmin.Type.t
ff_error_t
is the value type for ff_error
.
val write_error_t : write_error Irmin.Type.t
write_error_t
is the value type for write_error
.
module Private : sig ... end
Private functions, which might be used by the backends.
val to_private_node : node -> Private.Node.value Tree.or_error Lwt.t
val of_private_node : repo -> Private.Node.value -> node
val to_private_commit : commit -> Private.Commit.value
to_private_commit c
is the private commit object associated with the commit c
.
val of_private_commit : repo -> Private.Commit.value -> commit
of_private_commit r c
is the commit associated with the private commit object c
.
val save_contents :
[> Irmin.Perms.write ] Private.Contents.t ->
contents ->
hash Lwt.t
Save a content into the database
val save_tree :
?clear:bool ->
repo ->
[> Irmin.Perms.write ] Private.Contents.t ->
[> Irmin.Perms.read_write ] Private.Node.t ->
tree ->
hash Lwt.t
Save a tree into the database. Does not do any reads. If clear
is set (it is by default), the tree cache will be cleared after the save.