summaryrefslogtreecommitdiff
path: root/lib/git_presenters.ml
blob: cdd9caa1fd7f7f768de8bbe0cb21143db9e74d05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module Store = Git_unix.Store

let full_path path = Filename.concat Config.git_directory path

let store repo =
  let path = Fpath.v @@ full_path repo in
  Store.v ~dotgit:path path

let short_hash hash = String.sub hash 0 8

let repo_description repo =
  let description_path = Filename.concat (full_path repo) "description" in
  In_channel.with_open_text description_path In_channel.input_all

module User = struct
  type t = Git.User.t
end

module Commit = struct
  open Lwt_result.Syntax

  type t = {
    hash : string;
    parents : string list;
    author : User.t;
    message : string option;
  }

  let of_hash store h =
    let* v = Store.read store h in
    match v with
    | Git.Value.Commit c ->
        Lwt_result.return
          {
            hash = Store.Hash.to_hex h;
            parents = Store.Value.Commit.parents c |> List.map Store.Hash.to_hex;
            author = Store.Value.Commit.author c;
            message = Store.Value.Commit.message c;
          }
    | _ -> Lwt_result.fail @@ `Msg "value is not a commit"

  let recent_commits repo n =
    let* store = store repo in
    let* head = Store.Ref.resolve store Git.Reference.head in
    let rec walk acc hash count =
      if count = 0 then Lwt_result.return (List.rev acc)
      else
        let* commit = of_hash store hash in
        match commit.parents with
        | parent :: _ ->
            walk (commit :: acc) (Store.Hash.of_hex parent) (count - 1)
        | [] -> Lwt_result.return (List.rev (commit :: acc))
    in
    walk [] head n

  let of_id repo id =
    let open Lwt_result.Syntax in
    let* store = store repo in
    let id = Store.Hash.of_hex id in
    of_hash store id
end

module Branch = struct
  type t = { name : string }

  let all_branches repo =
    let open Lwt_result.Syntax in
    let* store = Git_unix.Store.v (Fpath.v repo) in
    let open Lwt.Syntax in
    let* refs = Store.Ref.list store in
    let branches =
      (* Filter these references for branches! *)
      List.map (function _, x -> x |> Store.Hash.to_hex) refs
    in
    Lwt_result.return branches
end
Copyright 2019--2025 Marius PETER