diff --git a/gitoxide-core/src/repository/clone.rs b/gitoxide-core/src/repository/clone.rs index e81cb6170d0..7e0530ef899 100644 --- a/gitoxide-core/src/repository/clone.rs +++ b/gitoxide-core/src/repository/clone.rs @@ -101,7 +101,7 @@ pub(crate) mod function { let ref_specs = remote.refspecs(gix::remote::Direction::Fetch); print_updates( &repo, - negotiate, + &negotiate, update_refs, ref_specs, fetch_outcome.ref_map, diff --git a/gitoxide-core/src/repository/fetch.rs b/gitoxide-core/src/repository/fetch.rs index df7ac1c9b66..b8987d4f099 100644 --- a/gitoxide-core/src/repository/fetch.rs +++ b/gitoxide-core/src/repository/fetch.rs @@ -10,6 +10,7 @@ pub struct Options { pub ref_specs: Vec, pub shallow: gix::remote::fetch::Shallow, pub handshake_info: bool, + pub negotiation_info: bool, } pub const PROGRESS_RANGE: std::ops::RangeInclusive = 1..=3; @@ -31,6 +32,7 @@ pub(crate) mod function { dry_run, remote, handshake_info, + negotiation_info, shallow, ref_specs, }: Options, @@ -66,27 +68,37 @@ pub(crate) mod function { update_refs, negotiate, dry_run: _, - } => print_updates( - &repo, - negotiate.unwrap_or_default(), - update_refs, - ref_specs, - res.ref_map, - &mut out, - err, - ), + } => { + let negotiate_default = Default::default(); + print_updates( + &repo, + negotiate.as_ref().unwrap_or(&negotiate_default), + update_refs, + ref_specs, + res.ref_map, + &mut out, + err, + )?; + if negotiation_info { + print_negotiate_info(&mut out, negotiate.as_ref())?; + } + Ok::<_, anyhow::Error>(()) + } Status::Change { update_refs, write_pack_bundle, negotiate, } => { - print_updates(&repo, negotiate, update_refs, ref_specs, res.ref_map, &mut out, err)?; + print_updates(&repo, &negotiate, update_refs, ref_specs, res.ref_map, &mut out, err)?; if let Some(data_path) = write_pack_bundle.data_path { writeln!(out, "pack file: \"{}\"", data_path.display()).ok(); } if let Some(index_path) = write_pack_bundle.index_path { writeln!(out, "index file: \"{}\"", index_path.display()).ok(); } + if negotiation_info { + print_negotiate_info(&mut out, Some(&negotiate))?; + } Ok(()) } }?; @@ -96,9 +108,23 @@ pub(crate) mod function { Ok(()) } + fn print_negotiate_info( + mut out: impl std::io::Write, + negotiate: Option<&gix::remote::fetch::outcome::Negotiate>, + ) -> std::io::Result<()> { + writeln!(out, "Negotiation Phase Information")?; + match negotiate { + Some(negotiate) => { + writeln!(out, "\t{:?}", negotiate.rounds)?; + writeln!(out, "\tnum commits traversed in graph: {}", negotiate.graph.len()) + } + None => writeln!(out, "\tno negotiation performed"), + } + } + pub(crate) fn print_updates( repo: &gix::Repository, - negotiate: gix::remote::fetch::outcome::Negotiate, + negotiate: &gix::remote::fetch::outcome::Negotiate, update_refs: gix::remote::fetch::refs::update::Outcome, refspecs: &[gix::refspec::RefSpec], mut map: gix::remote::fetch::RefMap, diff --git a/src/plumbing/main.rs b/src/plumbing/main.rs index 335144bb23a..1253c031601 100644 --- a/src/plumbing/main.rs +++ b/src/plumbing/main.rs @@ -189,6 +189,7 @@ pub fn main() -> Result<()> { Subcommands::Fetch(crate::plumbing::options::fetch::Platform { dry_run, handshake_info, + negotiation_info, remote, shallow, ref_spec, @@ -198,6 +199,7 @@ pub fn main() -> Result<()> { dry_run, remote, handshake_info, + negotiation_info, shallow: shallow.into(), ref_specs: ref_spec, }; diff --git a/src/plumbing/options/mod.rs b/src/plumbing/options/mod.rs index ea0e30a0cd0..5122f6002c6 100644 --- a/src/plumbing/options/mod.rs +++ b/src/plumbing/options/mod.rs @@ -155,6 +155,10 @@ pub mod fetch { #[clap(long, short = 'H')] pub handshake_info: bool, + /// Print statistics about negotiation phase. + #[clap(long, short = 's')] + pub negotiation_info: bool, + #[clap(flatten)] pub shallow: ShallowOptions,