git-mirage

MirageOS backend for the Git protocol(s)
IN THIS PACKAGE
Module Git_mirage . Sync . Tcp
module Endpoint : Git.Sync.ENDPOINT with type t = endpoint
type error
val pp_error : error Fmt.t

Pretty-printer of error.

type command = [
| `Create of G.Hash.t * G.Reference.t(*

To create a new reference on the server.

*)
| `Delete of G.Hash.t * G.Reference.t(*

To delete an existing reference on the server - `Delete_refs needs to be available in both side as a Capability.t.

*)
| `Update of G.Hash.t * G.Hash.t * G.Reference.t(*

To update a reference from a commit hash to a new commit hash.

*)
]

A push command to interact with the server.

val pp_command : command Fmt.t

Pretty-printer of command.

val push : G.t -> push: ( (G.Hash.t * G.Reference.t * bool) list -> (G.Hash.t list * command list) Lwt.t ) -> ?capabilities:Git.Capability.t list -> Endpoint.t -> ( ( G.Reference.t, G.Reference.t * string ) result list, error ) result Lwt.t
val ls : G.t -> ?capabilities:Git.Capability.t list -> Endpoint.t -> ( (G.Hash.t * G.Reference.t * bool) list, error ) result Lwt.t
val fetch : G.t -> ?shallow:G.Hash.t list -> ?capabilities:Git.Capability.t list -> notify:( G.Hash.t Git.Sync.shallow_update -> unit Lwt.t ) -> negociate: (( G.Hash.t Git.Sync.acks -> 'state -> ([ `Ready | `Done | `Again of G.Hash.Set.t ] * 'state) Lwt.t ) * 'state) -> have:G.Hash.Set.t -> want: ( (G.Hash.t * G.Reference.t * bool) list -> (G.Reference.t * G.Hash.t) list Lwt.t ) -> ?deepen:[ `Depth of int | `Timestamp of int64 | `Ref of Git.Reference.t ] -> Endpoint.t -> ( (G.Reference.t * G.Hash.t) list * int, error ) result Lwt.t
val fetch_some : G.t -> ?capabilities:Git.Capability.t list -> references:G.Reference.t list G.Reference.Map.t -> Endpoint.t -> ( G.Hash.t G.Reference.Map.t * G.Reference.t list G.Reference.Map.t, error ) result Lwt.t

fetch_some git ?capabilities ~references repository will fetch some remote references specified by references.

references is a map which:

  • the key is the remote reference.
  • the value is a list of local references - which may not exist yet.

Then, the function will try to download all of these remote references and returns 2 maps:

  • the first map contains all local references updated by the new hash. This new hash is come from the server as the downloaded remote reference asked by the client by references. Then, from associated local references with remote references, we updated them with the associated hash.

    For example, if references is:

    { "refs/heads/master": [
    "refs/remotes/origin/master" ; "refs/heads/master" ] } 

    We will update (or create) "refs/remotes/origin/master" and "refs/heads/master" with the new hash downloaded from the remote reference "refs/heads/master" only if it's necessary (only if we did not find the hash referenced by "refs/heads/master" in the local store).

  • the second map is a subset of references which contains all binder of:

    • remote references which does not exist on the server side.
    • remote references which references to an already existing in the local store hash.

The client should not put the same local reference as a value of some remote references. The client can define non-existing remote references (then, they appear on the second map). The client can want to set non-existing local references - we will create them.

If the processus encountered an error when it updates references, it leaves but, it did partially some update on some local references.

fetch_all git ?capabilities ~references repository has the same semantic than fetch_some for any remote references found on references. However, fetch all will download all remote references available on the server (and whose hash is not available on the local store). If these remote references are not associated with some local references, we return a third map which contains these remote references binded with the new hash downloaded.

We don't notice any non-downloaded remote references not found on the references map and whose hash already exists on the local store.

Then, the client can bind these new hashes with specific local references or just give up.

val fetch_one : G.t -> ?capabilities:Git.Capability.t list -> reference:(G.Reference.t * G.Reference.t list) -> Endpoint.t -> ( [ `AlreadySync | `Sync of G.Hash.t G.Reference.Map.t ], error ) result Lwt.t

fetch_one git ?capabilities ~reference repository is a specific call of fetch_some with only one reference. Then, it retuns:

  • `AlreadySync if the hash of the requested reference already exists on the local store
  • `Sync updated if we downloaded new_hash and set local_ref with this new hash.
val pp_fetch_one : [ `AlreadySync | `Sync of G.Hash.t G.Reference.Map.t ] Fmt.t
val clone : G.t -> ?capabilities:Git.Capability.t list -> reference:(G.Reference.t * G.Reference.t) -> Endpoint.t -> ( unit, error ) result Lwt.t
val update_and_create : G.t -> ?capabilities:Git.Capability.t list -> references:G.Reference.t list G.Reference.Map.t -> Endpoint.t -> ( ( G.Reference.t, G.Reference.t * string ) result list, error ) result Lwt.t

As fetch_some, update git ?capabilities ~references repository is the other side of the communication with a Git server and update and create remote references when it uploads local hashes.

reference is a map which:

  • the key is the local reference.
  • the value is a list of remote references - which may not exist yet.

Then, the function will try to upload all of these local references to the binded remote references. If binded remote reference does not exist on the server, we ask to the server to create and set it to the local hash.

For each update action, we check if the local store has the remote hash. In other case, we miss this action - that means, the local store is not synchronized with the server (and the client probably needs to fetch_some before).

Then, it returns a list of results. The Ok case with the remote reference which the server updated correctly and the Error case with the remote reference which the server encountered an error with a description of this error.

At this final stage, the function does not encountered any error during the commmunication - if it's the case, we did not do any modification on the server and return an error.

val pp_update_and_create : ( G.Reference.t, G.Reference.t * string ) result list Fmt.t