1+ pub use crate :: git:: { clone_to_path, get_remote_default_branch} ;
2+
13use crate :: config:: Config ;
4+ use crate :: git:: build_fetch_options;
25use anyhow:: { Context , Result , anyhow} ;
36use git2:: Repository ;
47use std:: io:: { self , Write } ;
@@ -93,86 +96,6 @@ pub fn parse_repo_url(input: &str) -> Result<String> {
9396 }
9497}
9598
96- pub fn get_remote_default_branch ( url : & str ) -> Result < String > {
97- let temp_dir = tempfile:: tempdir ( ) . context ( "Failed to create temporary directory" ) ?;
98-
99- let repository =
100- Repository :: init ( temp_dir. path ( ) ) . context ( "Failed to initialize temp repository" ) ?;
101-
102- let mut remote = repository
103- . remote_anonymous ( url)
104- . context ( "Failed to create remote" ) ?;
105-
106- remote
107- . connect ( git2:: Direction :: Fetch )
108- . context ( "Failed to connect to remote" ) ?;
109-
110- if let Ok ( default_branch) = remote. default_branch ( ) {
111- remote. disconnect ( ) . context ( "Failed to disconnect remote" ) ?;
112-
113- let branch_name = default_branch
114- . as_str ( )
115- . context ( "Failed to read default branch name" ) ?
116- . trim_start_matches ( "refs/heads/" )
117- . to_string ( ) ;
118-
119- if !branch_name. is_empty ( ) {
120- return Ok ( branch_name) ;
121- }
122- } else {
123- remote. disconnect ( ) . context ( "Failed to disconnect remote" ) ?;
124- }
125-
126- let mut fetch_options = git2:: FetchOptions :: new ( ) ;
127- fetch_options. download_tags ( git2:: AutotagOption :: All ) ;
128-
129- let remote_name = remote. name ( ) . unwrap_or ( "origin" ) ;
130- let refspec = format ! ( "+refs/heads/*:refs/remotes/{}/*" , remote_name) ;
131-
132- remote
133- . fetch ( & [ & refspec] , Some ( & mut fetch_options) , None )
134- . context ( "Failed to fetch from remote" ) ?;
135-
136- let default_branch = find_default_branch ( & repository) ?;
137-
138- Ok ( default_branch)
139- }
140-
141- fn find_default_branch ( repository : & Repository ) -> Result < String > {
142- let branches = repository. branches ( Some ( git2:: BranchType :: Remote ) ) ?;
143-
144- let mut candidates: Vec < ( String , bool ) > = Vec :: new ( ) ;
145-
146- for branch_result in branches {
147- let ( branch, _) = branch_result. context ( "Failed to iterate branches" ) ?;
148- let name_result = branch. name ( ) . context ( "Failed to get branch name" ) ?;
149- if let Some ( branch_name) = name_result {
150- if branch_name. ends_with ( "/HEAD" ) {
151- continue ;
152- }
153- let is_main = branch_name == "origin/main" ;
154- let is_master = branch_name == "origin/master" ;
155- let is_preferred = is_main || is_master;
156- candidates. push ( ( branch_name. to_string ( ) , is_preferred) ) ;
157- }
158- }
159-
160- candidates. sort_by ( |candidate_a, candidate_b| {
161- let ( _, a_is_preferred) = candidate_a;
162- let ( _, b_is_preferred) = candidate_b;
163- match ( a_is_preferred, b_is_preferred) {
164- ( true , false ) => std:: cmp:: Ordering :: Less ,
165- ( false , true ) => std:: cmp:: Ordering :: Greater ,
166- _ => candidate_a. 0 . cmp ( & candidate_b. 0 ) ,
167- }
168- } ) ;
169-
170- candidates
171- . first ( )
172- . map ( |( branch_name, _) | branch_name. trim_start_matches ( "origin/" ) . to_string ( ) )
173- . ok_or_else ( || anyhow ! ( "No branches found in remote repository" ) )
174- }
175-
17699pub fn has_unpushed_changes ( path : & Path ) -> bool {
177100 let repository = match Repository :: open ( path) {
178101 Ok ( repo) => repo,
@@ -259,24 +182,6 @@ pub fn backup_existing(source: &Path) -> Result<PathBuf> {
259182 Ok ( backup_path)
260183}
261184
262- pub fn clone_to_path ( url : & str , branch : & str , target : & Path ) -> Result < ( ) > {
263- let mut fetch_options = git2:: FetchOptions :: new ( ) ;
264- fetch_options. download_tags ( git2:: AutotagOption :: All ) ;
265-
266- let mut builder = git2:: build:: RepoBuilder :: new ( ) ;
267- builder. fetch_options ( fetch_options) ;
268-
269- if !branch. is_empty ( ) {
270- builder. branch ( branch) ;
271- }
272-
273- builder
274- . clone ( url, target)
275- . context ( format ! ( "Failed to clone from {}" , url) ) ?;
276-
277- Ok ( ( ) )
278- }
279-
280185pub fn update_existing ( path : & Path ) -> Result < ( ) > {
281186 let repository = Repository :: open ( path) . context ( "Failed to open existing repository" ) ?;
282187
@@ -286,8 +191,7 @@ pub fn update_existing(path: &Path) -> Result<()> {
286191 ) ) ;
287192 }
288193
289- let mut fetch_options = git2:: FetchOptions :: new ( ) ;
290- fetch_options. download_tags ( git2:: AutotagOption :: All ) ;
194+ let mut fetch_options = build_fetch_options ( ) ;
291195
292196 let remotes = repository. remotes ( ) . context ( "Failed to get remotes" ) ?;
293197
0 commit comments