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
What is not supported
- No server-side operations are currently supported.
- No GC.
- Updates, merge and rebase are not supported. Use irmin instead.
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 main branch (reference) *)
let* commit_id = Store.Ref.resolve store Git.Reference.main 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.