summaryrefslogtreecommitdiff
path: root/lib/git_helpers.ml
diff options
context:
space:
mode:
Diffstat (limited to 'lib/git_helpers.ml')
-rw-r--r--lib/git_helpers.ml72
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
Copyright 2019--2025 Marius PETER