Handle missing HEAD refs without assuming master

Commit
6b85d6bbd7d0aebc7424bf25ccc8722decbe1ac4
Author
Codex AI Agent <codex-ai@openai.invalid>
Author date
Committer
Codex AI Agent <codex-ai@openai.invalid>
Committer date
Changed files
lib/resolvers.ml
index d96cfd13..b223194e 100644..100644
@@ -76,6 +76,56 @@
76 76
77 77 let short_hash hash = String.sub hash 0 8
78 78
79 Added: let branch_ref name = Git.Reference.v ("refs/heads/" ^ name)
80 Added:
81 Added: let fallback_branch_candidates () =
82 Added: let add acc name =
83 Added: if List.mem name acc then acc else acc @ [ name ]
84 Added: in
85 Added: let candidates = [] in
86 Added: let candidates = add candidates config.default_branch in
87 Added: let candidates = add candidates "main" in
88 Added: add candidates "master"
89 Added:
90 Added: let resolve_head_hash store =
91 Added: let fail_store_error err =
92 Added: Lwt_result.fail (`Msg (Fmt.str "%a" Store.pp_error err))
93 Added: in
94 Added: let rec try_references = function
95 Added: | [] ->
96 Added: let open Lwt.Syntax in
97 Added: let* references = Store.Ref.list store in
98 Added: let branches =
99 Added: references
100 Added: |> List.map fst
101 Added: |> List.filter_map (fun reference ->
102 Added: let name = Git.Reference.to_string reference in
103 Added: if String.starts_with ~prefix:"refs/heads/" name then
104 Added: Some (name, reference)
105 Added: else None)
106 Added: |> List.sort (fun (a, _) (b, _) -> String.compare a b)
107 Added: in
108 Added: let rec try_branches = function
109 Added: | [] -> Lwt_result.fail (`Msg "no branch could be resolved for repository")
110 Added: | (_, reference) :: rest ->
111 Added: Lwt.bind (Store.Ref.resolve store reference) @@ function
112 Added: | Ok hash -> Lwt_result.return hash
113 Added: | Error (`Reference_not_found _) -> try_branches rest
114 Added: | Error err -> fail_store_error err
115 Added: in
116 Added: try_branches branches
117 Added: | reference :: rest ->
118 Added: Lwt.bind (Store.Ref.resolve store reference) @@ function
119 Added: | Ok hash -> Lwt_result.return hash
120 Added: | Error (`Reference_not_found _) -> try_references rest
121 Added: | Error err -> fail_store_error err
122 Added: in
123 Added: Lwt.bind (Store.Ref.resolve store Git.Reference.head) @@ function
124 Added: | Ok hash -> Lwt_result.return hash
125 Added: | Error (`Reference_not_found _) ->
126 Added: try_references (List.map branch_ref (fallback_branch_candidates ()))
127 Added: | Error err -> fail_store_error err
128 Added:
79 129 module Commit = struct
80 130 type user = Git.User.t
81 131
@@ -104,7 +154,7 @@
104 154
105 155 let head repo =
106 156 let* store = store repo in
107 Removed: let* hash = Store.Ref.resolve store Git.Reference.head in
157 Added: let* hash = resolve_head_hash store in
108 158 let id = hash |> Store.Hash.to_hex in
109 159 of_id repo id
110 160
@@ -219,7 +269,7 @@
219 269
220 270 let head repo =
221 271 let* store = store repo in
222 Removed: let* hash = Store.Ref.resolve store Git.Reference.head in
272 Added: let* hash = resolve_head_hash store in
223 273 Lwt_result.bind (Store.read store hash) @@ function
224 274 | Git.Value.Commit commit ->
225 275 let tree_id = Store.Value.Commit.tree commit |> Store.Hash.to_hex in
test/test_ogit.ml
index 068c5e80..93ba20b8 100644..100644
@@ -68,6 +68,13 @@
68 68 assert (git_dir = Filename.concat clone ".git")
69 69 | None -> failwith "expected a non-bare repository layout"
70 70
71 Added: let test_fallback_branch_candidates () =
72 Added: let names = Ogit.Resolvers.fallback_branch_candidates () in
73 Added: assert (List.length names >= 2);
74 Added: assert (List.mem "main" names);
75 Added: assert (List.mem "master" names);
76 Added: assert (List.length (List.sort_uniq String.compare names) = List.length names)
77 Added:
71 78 let () =
72 79 assert (Ogit.Resolvers.is_valid_repo_name "project.git");
73 80 assert (Ogit.Resolvers.is_valid_repo_name "project");
@@ -96,4 +103,5 @@
96 103 test_config_round_trip ();
97 104 test_config_location ();
98 105 test_description_reader ();
99 Removed: test_repository_layout ()
106 Added: test_repository_layout ();
107 Added: test_fallback_branch_candidates ()