···267267 | None -> None
268268 | Some url_str ->
269269 if Opam_repo.is_git_url url_str then
270270- let url, _branch = Opam_repo.normalize_git_url url_str in
271271- Some (pkg_name, url)
270270+ Some (pkg_name, Opam_repo.normalize_git_url url_str)
272271 else None
273272 with _ -> None
274273 with _ -> None)
+31-4
lib/opam_repo.ml
···3232 | false -> url
3333 in
3434 let uri = Uri.of_string url in
3535- let branch = Uri.fragment uri in
3636- let uri_without_fragment = Uri.with_fragment uri None in
3737- (uri_without_fragment, branch)
3535+ (* Strip fragment from dev-repo URL - branch comes from url field *)
3636+ Uri.with_fragment uri None
3737+3838+(** Extract branch from a URL string with optional #branch fragment *)
3939+let extract_branch_from_url url =
4040+ let url =
4141+ match String.starts_with ~prefix:"git+" url with
4242+ | true -> String.sub url 4 (String.length url - 4)
4343+ | false -> url
4444+ in
4545+ Uri.fragment (Uri.of_string url)
38463947module OP = OpamParserTypes.FullPos
4048···4755 match item.pelem with
4856 | OP.Variable (name, value) when name.pelem = "dev-repo" ->
4957 extract_string_value value
5858+ | _ -> None)
5959+ items
6060+6161+(** Find the 'src' field inside a 'url' section *)
6262+let find_url_src (items : OP.opamfile_item list) : string option =
6363+ List.find_map
6464+ (fun (item : OP.opamfile_item) ->
6565+ match item.pelem with
6666+ | OP.Section sec when sec.section_kind.pelem = "url" ->
6767+ (* Look for src field inside the section *)
6868+ List.find_map
6969+ (fun (inner : OP.opamfile_item) ->
7070+ match inner.pelem with
7171+ | OP.Variable (name, value) when name.pelem = "src" ->
7272+ extract_string_value value
7373+ | _ -> None)
7474+ sec.section_items.pelem
5075 | _ -> None)
5176 items
5277···118143 | Some url ->
119144 if not (is_git_url url) then Error (Not_git_remote (name, url))
120145 else
121121- let dev_repo, branch = normalize_git_url url in
146146+ let dev_repo = normalize_git_url url in
147147+ (* Extract branch from url field's src, not from dev-repo *)
148148+ let branch = Option.bind (find_url_src opamfile.file_contents) extract_branch_from_url in
122149 let depends = find_depends opamfile.file_contents in
123150 let synopsis = find_synopsis opamfile.file_contents in
124151 Ok (Package.create ~name ~version ~dev_repo ?branch ~depends ?synopsis ())
+8-6
lib/opam_repo.mli
···6969 Accepts URLs starting with "git+" or "git://" or ending with ".git", as well
7070 as SSH-style URLs like "git@github.com:...". *)
71717272-val normalize_git_url : string -> Uri.t * string option
7272+val normalize_git_url : string -> Uri.t
7373(** [normalize_git_url url] normalizes a git URL by removing the "git+" prefix
7474- if present, and extracts the branch from the URL fragment if present.
7575-7676- Returns [(uri, branch)] where [branch] is [Some b] if the URL had a
7777- fragment like "#main", or [None] otherwise.
7474+ and any fragment (branch) if present.
78757976 For example, "git+https://example.com/repo.git#main" becomes
8080- ("https://example.com/repo.git", Some "main"). *)
7777+ "https://example.com/repo.git". *)
7878+7979+val extract_branch_from_url : string -> string option
8080+(** [extract_branch_from_url url] extracts the branch from a URL fragment.
8181+8282+ For example, "git+https://example.com/repo.git#main" returns [Some "main"]. *)
81838284val scan_opam_files_for_deps : fs:_ Eio.Path.t -> Fpath.t -> string list
8385(** [scan_opam_files_for_deps ~fs dir_path] scans a directory for .opam files