git-api 0.1.1

git2-rs based utility library
Documentation
use git2::{Error, Remote};

use crate::auth::auth_callbacks;

/// 获取远程仓库的引用(refs)
/// 
/// 返回值:Vec<(ref_name, is_symref_target, symref_target_or_oid)>
pub fn remote_refs(repo_url: &str, username: &str, password: &str) -> Result<Vec<(String, bool, String)>, Error> {
    let callbacks = auth_callbacks(username, password);
    let mut remote = Remote::create_detached(repo_url)?; // Create a remote with the given URL in-memory
    remote.connect_auth(git2::Direction::Fetch, Some(callbacks), None)?; // Open a connection to a remote with callbacks and proxy settings
    // remote.connect(git2::Direction::Fetch)?; // Open a connection to a remote.

    // Get the remote repository's reference advertisement list.
    let result = remote.list()?.iter().map(|head| {
        let ref_name = head.name();
        let oid = head.oid();
        if let Some(target) = head.symref_target() {
            (ref_name.into(), true, target.into())
        } else {
            (ref_name.into(), false, oid.to_string())
        }
    }).collect();
    Ok(result)
}

/// 查询远程仓库的主分支
/// 
/// 返回值:主分支名,如:Some("master")
pub fn remote_default_branch(repo_url: &str, username: &str, password: &str) -> Result<Option<String>, Error> {
    let branchs = remote_refs(repo_url, username, password)?;
    let Some((_ref_name, _is_symref_target, default_branch)) = branchs.iter()
        .find(|(ref_name, is_symref_target, _symref_target_or_oid)| {
            ref_name == "HEAD" && *is_symref_target
        }) else {
            return Ok(None);
        };
    let default_branch = default_branch.replacen("refs/heads/", "", 1);
    Ok(Some(default_branch))
}