diff options
| author | Marius Peter <marius.peter@tutanota.com> | 2025-05-17 19:21:32 +0200 | 
|---|---|---|
| committer | Marius Peter <marius.peter@tutanota.com> | 2025-05-17 19:25:00 +0200 | 
| commit | 3073ec0e7e2e7f0a89dbc4d4851da2451aff2f62 (patch) | |
| tree | 609655c46583ad3fd7abd398f3546c29faa74d1b /lib | |
| parent | 59b321967f83385296c9ce92fb29ee7f6c8b75db (diff) | |
Add custom types.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/git_helpers.ml | 72 | 
1 files changed, 50 insertions, 22 deletions
| diff --git a/lib/git_helpers.ml b/lib/git_helpers.ml index 07b0d04..5e5d4cd 100644 --- a/lib/git_helpers.ml +++ b/lib/git_helpers.ml @@ -1,33 +1,61 @@ -type commit_info = { +open Lwt.Infix +module Store = Git_unix.Store +module Value = Git.Value + +type user_record = { name : string; email : string } + +type commit_record = {    hash : string; +  parents : string list; +  author : Git.User.t;    message : string option; -  author : string; -  date : string;  }  let full_path path = Filename.concat Config.git_directory path  let store repo_path =    let path = Fpath.v @@ full_path repo_path in -  Git_unix.Store.v ~dotgit:path path +  Store.v ~dotgit:path path + +let short_hash hash = String.sub hash 0 8 + +let repo_description repo_path = +  let description_path = Filename.concat (full_path repo_path) "description" in +  In_channel.with_open_text description_path In_channel.input_all -let latest_commits repo_path ~count = +(* Read a Git object and turn it into our [commit_record], or propagate an error. *) +let get_commit_record store h = +  Store.read store h >>= function +  | Ok (Value.Commit c) -> +      Lwt.return_ok +        { +          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; +        } +  | Ok _ -> Lwt.return_error (`Msg "object is not a commit") +  | Error e -> Lwt.return_error e + +let recent_commits repo_path n =    let open Lwt_result.Syntax in -  let* store_result = store repo_path in -  let* commits = Git.Commit.Make in -  commits - -let all_branches repo_path = -  let cmd = -    Printf.sprintf "git -C %s branch --format=%%(refname:short)" -    @@ full_path repo_path +  let* store = store repo_path in +  let* head = Store.Ref.resolve store Git.Reference.head in +  let rec walk acc hash count = +    if count = 0 then Lwt.return_ok (List.rev acc) +    else +      get_commit_record store hash >>= function +      | Error e -> Lwt.return_error e +      | Ok commit -> ( +          match commit.parents with +          | parent :: _ -> +              walk (commit :: acc) (Store.Hash.of_hex parent) (count - 1) +          | [] -> Lwt.return_ok (List.rev (commit :: acc)))    in -  Lwt.catch -    (fun () -> -      let%lwt output = Lwt_process.pread ("", [| "sh"; "-c"; cmd |]) in -      let branches = -        String.split_on_char '\n' output -        |> List.filter (fun s -> String.trim s <> "") -      in -      Lwt.return_ok branches) -    (fun exn -> Lwt.return_error (Printexc.to_string exn)) +  walk [] head n + +let get_commit repo_path id = +  let open Lwt_result.Syntax in +  let* store = store repo_path in +  let id = Store.Hash.of_hex id in +  get_commit_record store id | 
