@@ -32,8 +32,7 @@ module Remote = struct
3232 type nonrec t =
3333 { url : string
3434 ; default_branch : Object .resolved option Fiber .t
35- ; branches : Object .resolved String.Map .t Fiber .t
36- ; tags : Object .resolved String.Map .t Fiber .t
35+ ; refs : Object .resolved String.Map .t Fiber .t
3736 }
3837
3938 let default_branch t = t.default_branch
733732let remote =
734733 let hash = Re. (rep1 alnum) in
735734 let head_mark, head = Re. mark (Re. str " HEAD" ) in
736- let re =
737- Re. (
738- compile
739- @@ seq
740- [ bol
741- ; group hash
742- ; rep1 space
743- ; alt
744- [ head
745- ; seq
746- [ str " refs/"
747- ; group (alt [ str " heads" ; str " tags" ])
748- ; str " /"
749- ; group (rep1 any)
750- ]
751- ]
752- ])
753- in
735+ let ref = Re. (group (seq [ str " refs/" ; rep1 any ])) in
736+ let re = Re. (compile @@ seq [ bol; group hash; rep1 space; alt [ head; ref ] ]) in
754737 fun t ~url :(url_loc , url ) ->
755738 let f url =
756739 let command = [ " ls-remote" ; url ] in
@@ -776,37 +759,24 @@ let remote =
776759 ]
777760 | _ -> Git_error. raise_code_error git_error)
778761 in
779- let default_branch, branches, tags =
780- List. fold_left
781- hits
782- ~init: (None , [] , [] )
783- ~f: (fun (default_branch , branches , tags ) line ->
784- match Re. exec_opt re line with
785- | None -> default_branch, branches, tags
786- | Some group ->
787- let hash = Re.Group. get group 1 |> Object. of_sha1 |> Option. value_exn in
788- if Re.Mark. test group head_mark
789- then Some hash, branches, tags
790- else (
791- let name = Re.Group. get group 3 in
792- let entry = name, hash in
793- match Re.Group. get group 2 with
794- | "heads" -> default_branch, entry :: branches, tags
795- | "tags" -> default_branch, branches, entry :: tags
796- | type_ ->
797- Code_error. raise
798- " ls-remote matched unexpected type of ref"
799- [ " ref" , Dyn. string name
800- ; " hash" , Object. to_dyn hash
801- ; " type" , Dyn. string type_
802- ]))
762+ let default_branch, refs =
763+ List. fold_left hits ~init: (None , [] ) ~f: (fun (default_branch , refs ) line ->
764+ match Re. exec_opt re line with
765+ | None -> default_branch, refs
766+ | Some group ->
767+ let hash = Re.Group. get group 1 |> Object. of_sha1 |> Option. value_exn in
768+ if Re.Mark. test group head_mark
769+ then Some hash, refs
770+ else (
771+ let name = Re.Group. get group 2 in
772+ let entry = name, hash in
773+ default_branch, entry :: refs))
803774 in
804- default_branch, String.Map. of_list_exn branches, String.Map. of_list_exn tags )
775+ default_branch, String.Map. of_list_exn refs )
805776 in
806777 { Remote. url
807- ; default_branch = (Fiber_lazy. force refs >> | fun (v , _ , _ ) -> v)
808- ; branches = (Fiber_lazy. force refs >> | fun (_ , v , _ ) -> v)
809- ; tags = (Fiber_lazy. force refs >> | fun (_ , _ , v ) -> v)
778+ ; default_branch = Fiber_lazy. force refs >> | fst
779+ ; refs = Fiber_lazy. force refs >> | snd
810780 }
811781 in
812782 Table. find_or_add t.remotes ~f url
@@ -818,19 +788,31 @@ let fetch_resolved t (remote : Remote.t) revision =
818788;;
819789
820790let resolve_revision t (remote : Remote.t ) ~revision =
821- let * branches = remote.branches in
822- let * tags = remote.tags in
791+ let * refs = remote.refs in
823792 let obj =
824- match String.Map. find branches revision, String.Map. find tags revision with
825- | (Some _ as obj ), None -> obj
826- | None , (Some _ as obj ) -> obj
827- | None , None -> None
828- | Some branch_obj , Some tag_obj ->
829- (match Object. equal branch_obj tag_obj with
830- | true -> Some branch_obj
831- | false ->
832- User_error. raise
833- [ Pp. textf " Reference %S in remote %S is ambiguous" revision remote.url ])
793+ match String.Map. find refs revision with
794+ | Some _ as obj -> obj
795+ | None ->
796+ (* revision was not found as-is, try formatting as branch/tag *)
797+ let lookup_in format = String.Map. find refs (sprintf format revision) in
798+ let as_branch = lookup_in " refs/heads/%s" in
799+ let as_tag = lookup_in " refs/tags/%s" in
800+ (match as_branch, as_tag with
801+ | (Some _ as obj ), None -> obj
802+ | None , (Some _ as obj ) -> obj
803+ | None , None -> None
804+ | Some branch_obj , Some tag_obj ->
805+ (match Object. equal branch_obj tag_obj with
806+ | true -> Some branch_obj
807+ | false ->
808+ let hints =
809+ [ Pp. textf " If you want to specify a tag use refs/tags/%s" revision
810+ ; Pp. textf " If you want to specify a branch use refs/branches/%s" revision
811+ ]
812+ in
813+ User_error. raise
814+ ~hints
815+ [ Pp. textf " Reference %S in remote %S is ambiguous" revision remote.url ]))
834816 in
835817 match obj with
836818 | Some obj as s ->
0 commit comments