diff --git a/gitoxide-core/src/pack/receive.rs b/gitoxide-core/src/pack/receive.rs index 8270d244601..34cbd9c9e83 100644 --- a/gitoxide-core/src/pack/receive.rs +++ b/gitoxide-core/src/pack/receive.rs @@ -94,7 +94,6 @@ where .await?; let mut negotiate = Negotiate { refmap: &refmap }; gix::protocol::fetch( - &refmap, &mut negotiate, |read_pack, progress, should_interrupt| { receive_pack_blocking( @@ -123,7 +122,6 @@ where shallow_file: "no shallow file required as we reject it to keep it simple".into(), shallow: &Default::default(), tags: Default::default(), - expected_object_hash: Default::default(), reject_shallow_remote: true, }, ) diff --git a/gix-protocol/src/fetch/error.rs b/gix-protocol/src/fetch/error.rs index 6eab014b9c9..149268e5f12 100644 --- a/gix-protocol/src/fetch/error.rs +++ b/gix-protocol/src/fetch/error.rs @@ -4,11 +4,6 @@ pub enum Error { #[error("Could not decode server reply")] FetchResponse(#[from] crate::fetch::response::Error), - #[error("Cannot fetch from a remote that uses {remote} while local repository uses {local} for object hashes")] - IncompatibleObjectHash { - local: gix_hash::Kind, - remote: gix_hash::Kind, - }, #[error(transparent)] Negotiate(#[from] crate::fetch::negotiate::Error), #[error(transparent)] @@ -26,11 +21,6 @@ pub enum Error { LockShallowFile(#[from] gix_lock::acquire::Error), #[error("Receiving objects from shallow remotes is prohibited due to the value of `clone.rejectShallow`")] RejectShallowRemote, - #[error("None of the refspec(s) {} matched any of the {num_remote_refs} refs on the remote", refspecs.iter().map(|r| r.to_ref().instruction().to_bstring().to_string()).collect::>().join(", "))] - NoMapping { - refspecs: Vec, - num_remote_refs: usize, - }, #[error("Failed to consume the pack sent by the remove")] ConsumePack(Box), #[error("Failed to read remaining bytes in stream")] diff --git a/gix-protocol/src/fetch/function.rs b/gix-protocol/src/fetch/function.rs index e215ffd038c..57b7549cba6 100644 --- a/gix-protocol/src/fetch/function.rs +++ b/gix-protocol/src/fetch/function.rs @@ -1,13 +1,12 @@ use crate::fetch::{ - negotiate, Context, Error, Negotiate, NegotiateOutcome, Options, Outcome, ProgressId, RefMap, Shallow, Tags, + negotiate, Context, Error, Negotiate, NegotiateOutcome, Options, Outcome, ProgressId, Shallow, Tags, }; use crate::{fetch::Arguments, transport::packetline::read::ProgressAction}; use gix_features::progress::DynNestedProgress; use std::path::Path; use std::sync::atomic::{AtomicBool, Ordering}; -/// Perform one fetch operation, relying on a `transport`, right after a [`ref_map`](RefMap::new()) was created so -/// it's clear what the remote has. +/// Perform one fetch operation, relying on a `transport`. /// `negotiate` is used to run the negotiation of objects that should be contained in the pack, *if* one is to be received. /// `progress` and `should_interrupt` is passed to all potentially long-running parts of the operation. /// @@ -31,7 +30,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; /// to inform about all the changes that were made. #[maybe_async::maybe_async] pub async fn fetch( - ref_map: &RefMap, negotiate: &mut impl Negotiate, consume_pack: impl FnOnce(&mut dyn std::io::BufRead, &mut dyn DynNestedProgress, &AtomicBool) -> Result, mut progress: P, @@ -46,7 +44,6 @@ pub async fn fetch( shallow_file, shallow, tags, - expected_object_hash, reject_shallow_remote, }: Options<'_>, ) -> Result, Error> @@ -57,16 +54,6 @@ where E: Into>, { let _span = gix_trace::coarse!("gix_protocol::fetch()"); - - if ref_map.mappings.is_empty() && !ref_map.remote_refs.is_empty() { - let mut specs = ref_map.refspecs.clone(); - specs.extend(ref_map.extra_refspecs.clone()); - return Err(Error::NoMapping { - refspecs: specs, - num_remote_refs: ref_map.remote_refs.len(), - }); - } - let v1_shallow_updates = handshake.v1_shallow_updates.take(); let protocol_version = handshake.server_protocol_version; @@ -93,13 +80,6 @@ where } let (shallow_commits, mut shallow_lock) = add_shallow_args(&mut arguments, shallow, &shallow_file)?; - if ref_map.object_hash != expected_object_hash { - return Err(Error::IncompatibleObjectHash { - local: expected_object_hash, - remote: ref_map.object_hash, - }); - } - let negotiate_span = gix_trace::detail!( "negotiate", protocol_version = handshake.server_protocol_version as usize diff --git a/gix-protocol/src/fetch/types.rs b/gix-protocol/src/fetch/types.rs index bd80eb2c3c3..207266eb301 100644 --- a/gix-protocol/src/fetch/types.rs +++ b/gix-protocol/src/fetch/types.rs @@ -12,8 +12,6 @@ pub struct Options<'a> { pub shallow: &'a Shallow, /// Describe how to handle tags when fetching. pub tags: Tags, - /// The hash the remote repository is expected to use, as it's what the local repository is initialized as. - pub expected_object_hash: gix_hash::Kind, /// If `true`, if we fetch from a remote that only offers shallow clones, the operation will fail with an error /// instead of writing the shallow boundary to the shallow file. pub reject_shallow_remote: bool, diff --git a/gix/src/remote/connection/fetch/error.rs b/gix/src/remote/connection/fetch/error.rs index 2c868e75b04..915175a4411 100644 --- a/gix/src/remote/connection/fetch/error.rs +++ b/gix/src/remote/connection/fetch/error.rs @@ -40,6 +40,11 @@ pub enum Error { feature: &'static str, description: &'static str, }, + #[error("None of the refspec(s) {} matched any of the {num_remote_refs} refs on the remote", refspecs.iter().map(|r| r.to_ref().instruction().to_bstring().to_string()).collect::>().join(", "))] + NoMapping { + refspecs: Vec, + num_remote_refs: usize, + }, #[error("Could not write 'shallow' file to incorporate remote updates after fetching")] WriteShallowFile(#[from] crate::shallow::write::Error), #[error("'shallow' file could not be locked in preparation for writing changes")] diff --git a/gix/src/remote/connection/fetch/receive_pack.rs b/gix/src/remote/connection/fetch/receive_pack.rs index 2b7cd59a3bf..ab474bb50c3 100644 --- a/gix/src/remote/connection/fetch/receive_pack.rs +++ b/gix/src/remote/connection/fetch/receive_pack.rs @@ -73,14 +73,32 @@ where P: gix_features::progress::NestedProgress, P::SubProgress: 'static, { + let ref_map = &self.ref_map; + if ref_map.mappings.is_empty() && !ref_map.remote_refs.is_empty() { + let mut specs = ref_map.refspecs.clone(); + specs.extend(ref_map.extra_refspecs.clone()); + return Err(Error::NoMapping { + refspecs: specs, + num_remote_refs: ref_map.remote_refs.len(), + }); + } + let mut con = self.con.take().expect("receive() can only be called once"); let mut handshake = con.handshake.take().expect("receive() can only be called once"); let repo = con.remote.repo; + + let expected_object_hash = repo.object_hash(); + if ref_map.object_hash != expected_object_hash { + return Err(Error::IncompatibleObjectHash { + local: expected_object_hash, + remote: ref_map.object_hash, + }); + } + let fetch_options = gix_protocol::fetch::Options { shallow_file: repo.shallow_file(), shallow: &self.shallow, tags: con.remote.fetch_tags, - expected_object_hash: repo.object_hash(), reject_shallow_remote: repo .config .resolved @@ -95,7 +113,7 @@ where user_agent: repo.config.user_agent_tuple(), trace_packetlines: con.trace, }; - let ref_map = &self.ref_map; + let negotiator = repo .config .resolved @@ -137,7 +155,6 @@ where let mut write_pack_bundle = None; let res = gix_protocol::fetch( - ref_map, &mut negotiate, |reader, progress, should_interrupt| -> Result { let mut may_read_to_end = false; diff --git a/tests/journey/gix.sh b/tests/journey/gix.sh index dd180cff8c7..a7acfc8f70e 100644 --- a/tests/journey/gix.sh +++ b/tests/journey/gix.sh @@ -109,7 +109,7 @@ title "gix (with repository)" # for some reason, on CI the daemon always shuts down before we can connect, # or isn't actually ready despite having accepted the first connection already. - (with "git:// protocol" + (not_on_ci with "git:// protocol" launch-git-daemon (with "version 1" it "generates the correct output" && { @@ -278,7 +278,7 @@ title "gix commit-graph" ) ) fi - (with "git:// protocol" + (not_on_ci with "git:// protocol" launch-git-daemon (with "version 1" (with "NO output directory"