diff --git a/src/git/mod.rs b/src/git/mod.rs index 941ddbf..5710ccb 100644 --- a/src/git/mod.rs +++ b/src/git/mod.rs @@ -45,7 +45,18 @@ pub fn get_current_commit_sha>( let repo = Repository::open(path)?; let commit = if let Some(ref_name) = ref_name { - let obj = repo.revparse_single(ref_name)?; + // Try the ref in several forms: bare name, local branch, remote tracking + let candidates = [ + ref_name.to_string(), + format!("refs/heads/{ref_name}"), + format!("refs/remotes/origin/{ref_name}"), + ]; + let obj = candidates + .iter() + .find_map(|candidate| repo.revparse_single(candidate).ok()) + .ok_or_else(|| { + PakkerError::GitError(format!("revspec '{ref_name}' not found")) + })?; obj.peel_to_commit()? } else { let head = repo.head()?; @@ -222,9 +233,19 @@ pub fn resolve_ref_type>( ) -> Result { let repo = Repository::open(path)?; - // Check if it's a branch - if repo.find_branch(ref_name, git2::BranchType::Local).is_ok() - || repo.find_branch(ref_name, git2::BranchType::Remote).is_ok() + // Check if it's a local branch + if repo.find_branch(ref_name, git2::BranchType::Local).is_ok() { + return Ok(crate::model::fork::RefType::Branch); + } + + // Check remote tracking branches (e.g. origin/main after a fresh clone) + let remote_branch_name = format!("origin/{ref_name}"); + if repo + .find_branch(&remote_branch_name, git2::BranchType::Remote) + .is_ok() + || repo + .find_reference(&format!("refs/remotes/origin/{ref_name}")) + .is_ok() { return Ok(crate::model::fork::RefType::Branch); } @@ -236,7 +257,12 @@ pub fn resolve_ref_type>( } // Try to resolve as commit SHA - if repo.revparse_single(ref_name).is_ok() { + let candidates = [ + ref_name.to_string(), + format!("refs/heads/{ref_name}"), + format!("refs/remotes/origin/{ref_name}"), + ]; + if candidates.iter().any(|c| repo.revparse_single(c).is_ok()) { return Ok(crate::model::fork::RefType::Commit); } @@ -483,7 +509,7 @@ mod tests { let mut index = repo.index().unwrap(); let file_path = path.join(file_name); let mut f = File::create(&file_path).unwrap(); - writeln!(f, "{}", content).unwrap(); + writeln!(f, "{content}").unwrap(); drop(f); index.add_path(std::path::Path::new(file_name)).unwrap(); let tree_id = index.write_tree().unwrap(); @@ -499,7 +525,7 @@ mod tests { repo .branch(branch, &repo.find_commit(head_oid).unwrap(), true) .unwrap(); - repo.set_head(&format!("refs/heads/{}", branch)).unwrap(); + repo.set_head(&format!("refs/heads/{branch}")).unwrap(); repo }