History

Assure that --deepen 0 (despite allowed) doesn't actually confuse the server.

Git does everything except an actual attempt to negotiate for fetching a pack in order to apply purge rules for references for instance, and we do the same.

Sebastian Thiel committed 3 years ago

Commit b43ea6b1 parent c502fa84 files · +64 −9Browse files

Unified · Split

4 files
  1. Makefile +1 −0
  2. gix/src/remote/connection/fetch/negotiate.rs +12 −2
  3. gix/src/remote/connection/fetch/receive_pack.rs +2 −1
  4. gix/tests/remote/fetch.rs +49 −6
Makefile+1−0
@@ -170,6 +170,7 @@ unit-tests: ## run all unit tests · 169 unmodified lines
170 && cargo test --features blocking-network-client \170 && cargo test --features blocking-network-client \
171 && cargo test --features regex171 && cargo test --features regex
172 cd gitoxide-core && cargo test --lib172 cd gitoxide-core && cargo test --lib
173# cd gix && cargo test --features async-network-client-async-std \ not being run as it's flaky even locally
173 174
174nextest: ## run tests with `cargo nextest` (all unit-tests, no doc-tests, faster)175nextest: ## run tests with `cargo nextest` (all unit-tests, no doc-tests, faster)
175 cargo nextest run --all176 cargo nextest run --all
gix/src/remote/connection/fetch/negotiate.rs+12−2
@@ -1,3 +1,4 @@
1use crate::remote::fetch;
1use gix_refspec::RefSpec;2use gix_refspec::RefSpec;
2 3
3/// The way the negotiation is performed4/// The way the negotiation is performed
@@ -27,12 +28,21 @@ pub(crate) fn one_round( · 23 unmodified lines
27 fetch_tags: crate::remote::fetch::Tags,28 fetch_tags: crate::remote::fetch::Tags,
28 arguments: &mut gix_protocol::fetch::Arguments,29 arguments: &mut gix_protocol::fetch::Arguments,
29 _previous_response: Option<&gix_protocol::fetch::Response>,30 _previous_response: Option<&gix_protocol::fetch::Response>,
30 wants_shallow_change: Option<&[RefSpec]>,31 wants_shallow_change: Option<(&fetch::Shallow, &[RefSpec])>,
31) -> Result<bool, Error> {32) -> Result<bool, Error> {
32 let tag_refspec_to_ignore = fetch_tags33 let tag_refspec_to_ignore = fetch_tags
33 .to_refspec()34 .to_refspec()
34 .filter(|_| matches!(fetch_tags, crate::remote::fetch::Tags::Included));35 .filter(|_| matches!(fetch_tags, crate::remote::fetch::Tags::Included));
35 let non_wildcard_specs_only = wants_shallow_change;36 let (shallow, non_wildcard_specs_only) = wants_shallow_change
37 .map(|(a, b)| (Some(a), Some(b)))
38 .unwrap_or_default();
39
40 if let Some(shallow) = shallow {
41 if *shallow == fetch::Shallow::Deepen(0) {
42 return Ok(true);
43 }
44 }
45
36 match algo {46 match algo {
37 Algorithm::Naive => {47 Algorithm::Naive => {
38 assert_eq!(round, 1, "Naive always finishes after the first round, it claims.");48 assert_eq!(round, 1, "Naive always finishes after the first round, it claims.");
gix/src/remote/connection/fetch/receive_pack.rs+2−1
@@ -118,7 +118,8 @@ where · 117 unmodified lines
118 con.remote.fetch_tags,118 con.remote.fetch_tags,
119 &mut arguments,119 &mut arguments,
120 previous_response.as_ref(),120 previous_response.as_ref(),
121 (self.shallow != Shallow::NoChange).then(|| con.remote.refspecs(remote::Direction::Fetch)),121 (self.shallow != Shallow::NoChange)
122 .then(|| (&self.shallow, con.remote.refspecs(remote::Direction::Fetch))),
122 ) {123 ) {
123 Ok(_) if arguments.is_empty() => {124 Ok(_) if arguments.is_empty() => {
124 gix_protocol::indicate_end_of_interaction(&mut con.transport).await.ok();125 gix_protocol::indicate_end_of_interaction(&mut con.transport).await.ok();
gix/tests/remote/fetch.rs+49−6
@@ -107,17 +107,60 @@ mod blocking_and_async_io { · 106 unmodified lines
107 Ok(())107 Ok(())
108 }108 }
109 109
110 #[maybe_async::test(
111 feature = "blocking-network-client",
112 async(feature = "async-network-client-async-std", async_std::test)
113 )]
114 async fn fetch_shallow_deepen_zero_does_not_fail() -> crate::Result {
115 let (repo, tmp) = try_repo_rw_args("two-origins", ["--depth=2"], Mode::CloneWithShallowSupport)?;
116 let daemon = spawn_git_daemon_if_async(tmp.path().join("base"))?;
117 let remote = into_daemon_remote_if_async(
118 repo.head()?
119 .into_remote(Fetch)
120 .expect("present")?
121 .with_fetch_tags(fetch::Tags::Included),
122 daemon.as_ref(),
123 None,
124 );
125
126 let prev_commits = repo.head_id()?.ancestors().all()?.count();
127
128 let changes = remote
129 .connect(Fetch, gix::progress::Discard)
130 .await?
131 .prepare_fetch(Default::default())
132 .await?
133 .with_shallow(fetch::Shallow::Deepen(0))
134 .receive(&AtomicBool::default())
135 .await?;
136
137 assert!(
138 matches!(changes.status, Status::NoPackReceived { .. }),
139 "we didn't negotiate at all, but ran all other ref updates"
140 );
141 assert_eq!(
142 repo.head_id()?.ancestors().all()?.count(),
143 prev_commits,
144 "no more commits are available - we didn't fetch anything and there would be nothing to fetch"
145 );
146 Ok(())
147 }
148
110 #[maybe_async::test(149 #[maybe_async::test(
111 feature = "blocking-network-client",150 feature = "blocking-network-client",
112 async(feature = "async-network-client-async-std", async_std::test)151 async(feature = "async-network-client-async-std", async_std::test)
113 )]152 )]
114 async fn fetch_shallow_deepen_not_possible() -> crate::Result {153 async fn fetch_shallow_deepen_not_possible() -> crate::Result {
115 let (repo, _tmp) = try_repo_rw_args("two-origins", ["--depth=2"], Mode::CloneWithShallowSupport)?;154 let (repo, tmp) = try_repo_rw_args("two-origins", ["--depth=2"], Mode::CloneWithShallowSupport)?;
116 let remote = repo155 let daemon = spawn_git_daemon_if_async(tmp.path().join("base"))?;
117 .head()?156 let remote = into_daemon_remote_if_async(
118 .into_remote(Fetch)157 repo.head()?
119 .expect("present")?158 .into_remote(Fetch)
120 .with_fetch_tags(fetch::Tags::Included);159 .expect("present")?
160 .with_fetch_tags(fetch::Tags::Included),
161 daemon.as_ref(),
162 None,
163 );
121 164
122 assert_eq!(165 assert_eq!(
123 repo.shallow_commits()?.expect("shallow clone").as_slice(),166 repo.shallow_commits()?.expect("shallow clone").as_slice(),