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.
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.
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:
if strategy = `Set, the last write wins.
if strategy = `Test_and_set (default), the transaction is restarted.
if strategy = `Merge, concurrent changes are merged with f
v. If the merge has a conflict, the transaction is restarted.
Note: Irmin transactions provides snapshot isolation guarantees: reads and writes are isolated in every transaction, but only write conflicts are visible on commit.
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.
merge ~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>.
val history :
?depth:int ->?min:commit list->?max:commit list->t->History.t Lwt.t
history ?depth ?min ?max t is a view of the history of the store t, of depth at most depth, starting from the max (or from the t's head if the list of heads is empty) and stopping at min if specified.