use git2::{Direction, Error, PushOptions, RemoteCallbacks, Repository};
use crate::error::SheepError;
use crate::repo::{reference, ssh};
pub struct GitRemotes;
impl GitRemotes {
pub fn new() -> Self {
GitRemotes {}
}
pub fn remote_url(&self,
repository: &Repository,
remote_name: &str) -> Result<String, SheepError> {
let remote = repository.find_remote(remote_name)?;
let url = remote.url().ok_or(SheepError::new("no url from remote"))?;
Ok(url.to_string())
}
pub fn push_branch(&self,
repository: &Repository,
branch_name: &str,
remote_name: &str) -> Result<(), Error> {
let ref_name = reference::branch_ref_name(branch_name);
self.push_ref(repository, &ref_name, remote_name)
}
pub fn push_tag(&self, repository: &Repository,
tag_name: &str,
remote_name: &str) -> Result<(), Error> {
let ref_name = reference::tag_ref_name(tag_name);
self.push_ref(repository, &ref_name, remote_name)
}
fn push_ref(&self, repository: &Repository,
ref_name: &str,
remote_name: &str) -> Result<(), Error> {
let mut callbacks = RemoteCallbacks::new();
ssh::add_credentials_to_callbacks(&mut callbacks);
let mut remote = repository.find_remote(remote_name)?;
remote.connect_auth(Direction::Push, Some(callbacks), None)?;
let mut push_callbacks = RemoteCallbacks::new();
ssh::add_credentials_to_callbacks(&mut push_callbacks);
let mut push_options = PushOptions::new();
push_options.remote_callbacks(push_callbacks);
let ref_spec = format!("{ref_name}:{ref_name}");
remote.push(&[ref_spec], Some(&mut push_options))
}
}