package git-mirage
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=aa07797e7cb6dc9ea970e760c01dd8b755312628b65c4db93a371254574b30a0
sha512=32ccf61727a17bf07d1d1941089c0462314adb6764ab6c2aececee5fcdff0fffce3a9d572eee499a4ec3f807d5fe9ec1b7175932c493c0f53c8549c5fb2aa7b6
Description
Published: 14 Feb 2023
README
ocaml-git -- Git format and protocol in pure OCaml
Support for on-disk and in-memory Git stores. Can read and write all the Git objects: blobs, trees, commits and tags. It can also handle pack files, pack indexes and index files (where the staging area lives - only for git-unix
package).
All the objects share a consistent API, and convenience functions are provided to manipulate the different objects. For instance, it is possible to make a pack file position independent (as the Zlib compression might change the relative offsets between the packed objects), to generate pack indexes from pack files, or to expand the filesystem of a given commit.
The library comes with some command-line tools called ogit-*
as a Proof-of-concept of the core library which shares a similar interface with git
, but where all operations are mapped to the API exposed by ocaml-git
(and hence using only OCaml code). However, these tools are not meant to be used. They are just examples of how to use ocaml-git
.
ocaml-git
wants to be a low-level library for irmin. By this fact, high-level commands such as a (patience) diff, git status
, etc. are not implemented.
As a MirageOS project, ocaml-git
is system agnostic. However, it provides a git-unix
package which uses UNIX syscall and is able to introspect a usual Git repository in a filesystem. However, ocaml-git
handles only Git objects and does not populate your filesystem as git
does. For example, Git_unix.Sync.fetch
does not give you files fetched from the repository but only synchronizes .git
with that repository.
The API documentation is available online.
Build, Install Instructions and Packages
To build and install the project, simply run:
$ opam install git
$ opam install git-unix
$ opam install git-mirage
Linking-trick
ocaml-git
uses 2 libraries with the linking-trick:
These libraries provide a C implementation and an OCaml implementation (mostly to be compatible with js_of_ocaml
). However, utop
or any a build-system such as ocamlbuild
are not able to choose between these implementations. So, you must explicitely choose one.
These libraries use virtual-library available with dune
. If your build-system is dune
, you should not have any problem about that where dune
is able to take the default implementation of these libraries.
What is supported
The loose object files can be read and written;
blobs (files)
trees (directories)
commits (revision history)
tags (annotated tags)
references (branch names)
The PACK files (collections of compressed loose objects using a binary-diff representation) and PACK indexes (indexes of pack files) can be read and written). The binary diff hunks are exposed using a high-level position-independent representation so that they can be manipulated more easily. Pack file can be created and is compressed.
The INDEX file (used as for managing the staging area) are fully supported, which means that
git diff
andgit status
will work as expected on a repository created by the library. This feature is only available forgit-unix
when it needs to introspect a file-system.Cloning and fetching (using various options) are fully supported for the Git protocol, the smart-HTTP protocol and
git+ssh
. A subset of the protocol capabilities are implemented (mainlythin-pack
,ofs-delta
,side-band-64k
andallow-reachable-sha1-in-want
).Pushing is still experimental and needs more testing.
An abstraction for Git Store Is available. Various store implementations are available:
An in-memory implementation;
A unix filesystem implementation;
What is not supported
No server-side operations are currently supported.
No GC.
Updates, merge and rebase are not supported. Use irmin instead.
Performance
Performance is comparable to the Git tool.
Example
This utop
example must run into the ocaml-git
repository when the given path is .
.
# ;; load necessary modules
# #require "checkseum.c" ;;
# #require "digestif.c" ;;
# #require "git-unix" ;;
# ;; we are going to use this project's local repository
# module Store = Git_unix.Store ;;
module Store = Git_unix.Store
# ;; this module is useful for finding git objects in a git store
# module Search = Git.Search.Make (Digestif.SHA1) (Store) ;;
module Search :
sig
type hash = Store.hash
type store = Store.t
type pred =
[ `Commit of hash
| `Tag of string * hash
| `Tree of string * hash
| `Tree_root of hash ]
val pred : store -> ?full:bool -> hash -> pred list Lwt.t
type path =
[ `Commit of path | `Path of string list | `Tag of string * path ]
val mem : store -> hash -> path -> bool Lwt.t
val find : store -> hash -> path -> hash option Lwt.t
end
# ;; we want to read the contents of a blob under name [filename]
# let read filename =
let open Lwt_result.Syntax in
(* get store located in current root's .git folder *)
let* store = Store.v (Fpath.v (Sys.getcwd ())) in
(* find obj-id pointed at by master branch (reference) *)
let* commit_id = Store.Ref.resolve store Git.Reference.master in
let open Lwt.Syntax in
(* find obj-id of of [filename] as a git blob *)
let* blob_id = Search.find store commit_id (`Commit (`Path [ filename ])) in
match blob_id with
| None -> Lwt.return (Error (`Not_found commit_id))
| Some hash ->
(* read contents of the blob *)
Store.read store hash
;;
val read : string -> (Store.Value.t, Store.error) Lwt_result.t = <fun>
# let pp =
let ok ppf = function
| Git.Value.Blob b -> Fmt.string ppf (Git.Blob.to_string b)
| _ -> Fmt.string ppf "#git-object"
in
Fmt.result ~ok ~error:Store.pp_error;;
val pp : ('_weak1 Git.Value.t, Store.error) result Fmt.t = <fun>
# Lwt_main.run Lwt.Infix.(read "README.md" >|= pp Fmt.stdout) ;;
ocaml-git -- Git format and protocol in pure OCaml
Support for on-disk and in-memory Git stores. Can read and write all
the Git objects: the usual blobs, trees, commits and tags but also
the pack files, pack indexes and the index file (where the staging area
lives).
[...]
()
License
MIT, see LICENSE.md file for its text.
Dependencies (33)
-
rresult
>= "0.6.0"
-
result
>= "1.5"
-
mirage-time
>= "2.0.1"
-
mirage-random
>= "2.0.0" & < "4.0.0"
-
mirage-flow
>= "2.0.1"
-
mirage-clock
>= "3.1.0"
-
lwt
>= "5.3.0"
-
ipaddr
>= "5.0.1"
-
fmt
>= "0.8.9"
-
domain-name
>= "0.3.0"
-
tcpip
>= "7.0.0"
- cstruct
-
x509
>= "0.16.2"
- ptime
-
mirage-crypto
< "1.0.0"
- ca-certs-nss
-
happy-eyeballs
>= "0.1.2"
-
happy-eyeballs-mirage
>= "0.1.2"
- hex
- uri
- tls-mirage
- tls
-
dns-client
>= "6.1.3"
-
dns
>= "6.1.3"
-
awa-mirage
>= "0.1.0" & < "0.2.0"
-
awa
>= "0.1.0" & < "0.2.0"
-
git-paf
= version
-
git
= version
-
base64
>= "3.5.0"
-
mimic-happy-eyeballs
>= "0.0.5" & < "0.0.8"
- mimic
-
dune
>= "2.8.0"
-
ocaml
>= "4.08.0"
Dev Dependencies (6)
-
ke
>= "0.4" & with-test
-
logs
>= "0.7.0" & with-test
-
cstruct
>= "6.0.0" & with-test
-
bigstringaf
>= "0.9.0" & with-test
-
alcotest-lwt
>= "1.2.3" & with-test
-
alcotest
>= "1.2.3" & with-test
Used by (2)
-
git-unix
= "3.12.0"
-
irmin-mirage
< "2.0.0"
Conflicts
None