Git object storage and pack files for Eio
1(* Copyright (c) 2024-2026 Thomas Gazagnaire <thomas@gazagnaire.org>
2
3 Permission to use, copy, modify, and distribute this software for any
4 purpose with or without fee is hereby granted, provided that the above
5 copyright notice and this permission notice appear in all copies.
6
7 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *)
14
15(** Git smart HTTP protocol for remote queries.
16
17 This module implements lightweight remote queries using the git smart HTTP
18 protocol, avoiding the need to clone or fetch to check remote refs.
19
20 Reference: {{:https://git-scm.com/docs/http-protocol}Git HTTP Protocol}
21
22 {2 Example}
23
24 {[
25 Eio_main.run @@ fun env ->
26 Eio.Switch.run @@ fun sw ->
27 let url = Uri.of_string "https://github.com/ocaml/ocaml.git" in
28 match Git.Remote.head ~sw ~env url ~branch:"trunk" with
29 | Some hash -> Format.printf "HEAD: %a@." Git.Hash.pp hash
30 | None -> Format.printf "Branch not found or remote unreachable@."
31 ]} *)
32
33type ref_entry = {
34 ref_name : string; (** Full ref name (e.g., "refs/heads/main") *)
35 hash : Hash.t; (** Commit hash the ref points to *)
36}
37(** A remote reference entry. *)
38
39val ls_remote :
40 ?session:Requests.t ->
41 sw:Eio.Switch.t ->
42 env:
43 < clock : _ Eio.Time.clock
44 ; net : _ Eio.Net.t
45 ; fs : Eio.Fs.dir_ty Eio.Path.t
46 ; .. > ->
47 Uri.t ->
48 ref_entry list option
49(** [ls_remote ?session ~sw ~env url] queries the remote for all refs.
50
51 Returns [Some refs] where [refs] is a list of ref entries, or [None] if the
52 query failed (network error, invalid URL, etc.).
53
54 Pass an existing [session] to reuse TLS connection and avoid reloading CA
55 certificates (which can be slow on macOS).
56
57 This uses the git smart HTTP protocol to query the remote without
58 downloading any objects, making it very fast for checking if updates are
59 available. *)
60
61val head :
62 ?session:Requests.t ->
63 sw:Eio.Switch.t ->
64 env:
65 < clock : _ Eio.Time.clock
66 ; net : _ Eio.Net.t
67 ; fs : Eio.Fs.dir_ty Eio.Path.t
68 ; .. > ->
69 Uri.t ->
70 branch:string ->
71 Hash.t option
72(** [head ?session ~sw ~env url ~branch] returns the commit hash of the
73 specified branch on the remote.
74
75 Returns [None] if the branch doesn't exist or the remote is unreachable.
76
77 Pass an existing [session] to reuse TLS connection and avoid reloading CA
78 certificates.
79
80 This is much faster than [git fetch] as it only queries ref information
81 without downloading any objects. *)
82
83val matches_local :
84 ?session:Requests.t ->
85 sw:Eio.Switch.t ->
86 env:
87 < clock : _ Eio.Time.clock
88 ; net : _ Eio.Net.t
89 ; fs : Eio.Fs.dir_ty Eio.Path.t
90 ; .. > ->
91 Uri.t ->
92 branch:string ->
93 local_hash:Hash.t ->
94 bool
95(** [matches_local ?session ~sw ~env url ~branch ~local_hash] returns [true] if
96 the remote branch points to the same commit as [local_hash].
97
98 Returns [false] if the remote is unreachable or the hashes differ.
99
100 Pass an existing [session] to reuse TLS connection and avoid reloading CA
101 certificates.
102
103 This is useful to determine if a fetch is needed - if the remote matches the
104 local tracking branch, no fetch is necessary. *)