use git2::{Cred, RemoteCallbacks}; use log::{debug, info}; use crate::util::find_ssh_key; pub(crate) fn default_callbacks<'s>() -> RemoteCallbacks<'s> { let mut callbacks = RemoteCallbacks::new(); let mut fail_next_call = false; let mut tried_agent = false; callbacks.credentials(move |url, username_from_url, allowed_types| { if fail_next_call { info!("Failed to get credentials for push"); return Err(git2::Error::from_str("Bad credentials.")); } debug!("getting credentials {url} {username_from_url:?} {allowed_types:?}"); match (allowed_types.is_ssh_key(), username_from_url) { (true, Some(username)) => { if !tried_agent { tried_agent = true; return Cred::ssh_key_from_agent(username); } fail_next_call = true; // This is our last try // If the agent failed, try using the default SSH key if let Some(key) = find_ssh_key() { Cred::ssh_key(username, None, key.as_path(), None) } else { Err(git2::Error::from_str( "Bad credentials. Ensure your key was added using ssh-add", )) } } (true, None) => Err(git2::Error::from_str("Couldn't get username from url")), _ => { return Err(git2::Error::from_str("https remotes are not (yet) supported")); } } }); callbacks.push_transfer_progress(|current, total, bytes| { debug!("progress: {}/{} ({} B)", current, total, bytes,); }); callbacks.transfer_progress(|p| { debug!("transfer: {}/{}", p.received_objects(), p.total_objects()); true }); callbacks.pack_progress(|stage, current, total| { debug!("packing: {:?} - {}/{}", stage, current, total); }); callbacks.push_update_reference(|reference, msg| { debug!("push_update_reference: '{}' {:?}", reference, msg); Ok(()) }); callbacks.update_tips(|name, a, b| { debug!("update tips: '{}' {} -> {}", name, a, b); if a != b { // let mut push_result = push_result.lock().unwrap(); // *push_result = PushResult::Success } true }); callbacks.sideband_progress(|data| { debug!("sideband transfer: '{}'", String::from_utf8_lossy(data).trim()); true }); callbacks }