sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>
On This Page
module C : Irmin.Contents.S
module R : Irmin.Ref.S
module H : Irmin.Hash.S
include Irmin.BC
with type key = C.Path.t
with type value = C.t
with type branch_id = R.t
with type commit_id = H.t
Branch-consistent stores are hierarchical 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 BC store in Irmin: persistent named branches and 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.
A persistent branch always has a unique ID, which is typically a string (the branch name). Thus, in order to use a persistent branch, you need to provide its name: see the of_branch_id function.
type commit_id = H.t
Type for commit identifiers. Similar to Git's commit SHA1s.
type branch_id = R.t
Type for persistent branch names. Branches usually share a common global namespace and it's the user's responsibility to avoid name clashes.
module Repo : sig ... end
A repository contains a set of branches.
A branch-consistent store is a hierarchical read-write store.
include Irmin.HRW with type key = C.Path.t with type value = C.t
Hierarchical read-write stores are read-write stores using paths as keys. They are a very simplified abstraction of filesystems.
include Irmin.RW with type key = C.Path.t with type value = C.t
update t k v
replaces the contents of k
by v
in t
. If k
is not already defined in t
, create a fresh binding. Raise Invalid_argument
if k
is the empty path.
compare_and_set t key ~test ~set
sets key
to set
only if the current value of key
is test
and in that case returns true
. If the current value of key
is different, it returns false
. None
means that the value does not have to exist or is removed.
Note: The operation is guaranteed to be atomic.
val master : 'a Irmin.Task.f -> Repo.t -> ('a -> t) Lwt.t
master repo task
is a function returning fresh store handles within the repository repo
, with fresh tasks computed using task
. The result is a persistent branch using the
ef.S.master
reference. This operation is cheap, can be repeated multiple times.
val task : t -> Irmin.task
task t
is the task associated to the store handle t
.
val of_branch_id : 'a Irmin.Task.f -> branch_id -> Repo.t -> ('a -> t) Lwt.t
of_branch_id t name
is the persistent branch named name
. Similar to master
, but use name
instead Ref.S.master
.
name t
is t
's branch name. Return None
if t
is not persistent.
update_branch t src
updates t
's contents with the contents of the branch named src
. Can cause data losses as it discard the current contents. Similar to git reset --hard <src>
.
val merge_branch :
t ->
?max_depth:int ->
?n:int ->
branch_id ->
unit Irmin.Merge.result Lwt.t
merge_branch t other
merges the contents of the branch named other
into t
. Similar to git merge <other>
.
Same as merge_branch
but raise Merge.Conflict
in case of conflict.
Temporary stores do not have stable names: instead they can be addressed using the hash of the current commit. These hashes are called heads in Irmin. 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 while performing the update.
Temporary stores are created using the BC.of_head
function.
val empty : 'a Irmin.Task.f -> Repo.t -> ('a -> t) Lwt.t
empty repo task
is a temporary, empty store. Becomes a normal temporary store after the first update.
val of_commit_id : 'a Irmin.Task.f -> commit_id -> Repo.t -> ('a -> t) Lwt.t
Create a temporary store, using the given commit_id
. The store will not persist as it has no persistent branch name.
head t
is the current head of the store t
. This works for both persistent and temporary stores. In the case of a persistent branch, this involves getting the the head associated with the branch's ID, so this may block. In the case of a temporary store, it simply returns the current head. Returns None
if the store has no contents. Similar to git
rev-parse HEAD
.
Same as head
but raise Invalid_argument
if the store does not have any contents.
head_ref t
is the branch ID that this store tracks (for persistent stores), the current head
commit (for temporary stores), or `Empty
for empty temporary stores.
update_head t h
updates t
's contents with the contents of the commit_id h
. Can cause data loss as it discards the current contents. Similar to git reset --hard <hash>
.
fast_forward_head t h
is similar to update_head
but the t
's head is updated to h
only if h
is stricly in the future of t
's current head. Return false
if it is not the case. If present, max_depth
or n
are used to limit the search space of the lowest common ancestors (see lcas
).
Same as update_head
but check that the value is test
before updating to set
. Use update
or merge
instead if possible.
val merge_head :
t ->
?max_depth:int ->
?n:int ->
commit_id ->
unit Irmin.Merge.result Lwt.t
merge_head t ?max_head ?n commit_id
merges the contents of the commit associated to commit_id
into t
. max_depth
is the maximal depth used for getting the lowest common ancestor. n
is the maximum number of lowest common ancestors. If present, max_depth
or n
are used to limit the search space of the lowest common ancestors (see lcas
).
Same as merge_head but raise Merge.Conflict
in case of a conflict.
val watch_head :
t ->
?init:commit_id ->
(commit_id Irmin.diff -> unit Lwt.t) ->
(unit -> unit Lwt.t) Lwt.t
watch_branch t f
calls f
every time the contents of t
's reference is updated. Do nothing if t
is not persistent. Return a clean-up function to remove the watch handler.
Note: even 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_id * value) ->
((commit_id * value) Irmin.diff -> unit Lwt.t) ->
(unit -> unit Lwt.t) 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 clone :
'a Irmin.Task.f ->
t ->
branch_id ->
[ `Ok of 'a -> t | `Duplicated_branch | `Empty_head ] Lwt.t
Clone the store t
, using the given branch name. Return Duplicated_branch
if a branch with the same name already exists and Empty_head
if t
has no head.
val clone_force : 'a Irmin.Task.f -> t -> branch_id -> ('a -> t) Lwt.t
Same as clone but delete and update the existing branch if a branch with the same name already exists.
val merge :
'a ->
?max_depth:int ->
?n:int ->
('a -> t) ->
into:('a -> t) ->
unit Irmin.Merge.result Lwt.t
merge x t i
merges t x
's current branch into i x
's current branch. After that operation, the two stores are still independent. Similar to git merge <branch>
.
FIXME Same as merge but raise Merge.Conflict
in case of a conflict.
val lcas :
'a ->
?max_depth:int ->
?n:int ->
('a -> t) ->
('a -> t) ->
[ `Ok of commit_id list | `Max_depth_reached | `Too_many_lcas ] Lwt.t
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 `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 `Too_many_lcas
if more lcas
are found.val lcas_branch :
t ->
?max_depth:int ->
?n:int ->
branch_id ->
[ `Ok of commit_id list | `Max_depth_reached | `Too_many_lcas ] Lwt.t
Same as lcas
but takes a branch ID as argument.
val lcas_head :
t ->
?max_depth:int ->
?n:int ->
commit_id ->
[ `Ok of commit_id list | `Max_depth_reached | `Too_many_lcas ] Lwt.t
Same as lcas
but takes a commit_id as argument.
module History : Graph.Sig.P with type V.t = commit_id
An history is a DAG of heads.
module Key = C.Path
Key
provides base functions on paths.
module Val : Irmin.Contents.S with type t = value
Val
provides base functions on user-defined, mergeable contents.
module Ref : Irmin.Ref.S with type t = branch_id
Ref
provides base functions on user-defined references.
module Hash : Irmin.Hash.S with type t = commit_id
Hash
provides base functions on commit IDs.
module Private : sig ... end
Private functions, which might be used by the backends.