Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

integrate gix-negotiate #861

Merged
merged 16 commits into from
Jun 6, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: Add fetch::Arguments::is_stateless() to aid proper use of arg…
…uments.

When arguments are used, haves are reset every round in stateless protocols, while
everything else is repeated. However, this also means that previously confirmed common
commits aren't repeated unless this is specifically implemented by the user of `Arguments`.

That caller can now easily determine if negotiations have to be compensated for.

Please note that `Arguments` explicitly doesn't implement repeating of all prior arguments, which
would also repeat a lot of *in-vain* haves.
Byron committed Jun 6, 2023
commit 877aa2921d8491d301945f86d5a69382e40fb081
12 changes: 12 additions & 0 deletions gix-protocol/src/fetch/arguments/mod.rs
Original file line number Diff line number Diff line change
@@ -78,6 +78,18 @@ impl Arguments {
pub fn can_use_include_tag(&self) -> bool {
self.supports_include_tag
}
/// Return true if we will use a stateless mode of operation, which can be decided in conjunction with `transport_is_stateless`.
///
/// * we are always stateless if the transport is stateless, i.e. doesn't support multiple interactions with a single connection.
/// * we are always stateless if the protocol version is `2`
/// * otherwise we may be stateful.
pub fn is_stateless(&self, transport_is_stateless: bool) -> bool {
#[cfg(any(feature = "async-client", feature = "blocking-client"))]
let res = transport_is_stateless || self.version == gix_transport::Protocol::V2;
#[cfg(not(any(feature = "async-client", feature = "blocking-client")))]
let res = transport_is_stateless;
res
}

/// Add the given `id` pointing to a commit to the 'want' list.
///
2 changes: 2 additions & 0 deletions gix-protocol/src/fetch/tests.rs
Original file line number Diff line number Diff line change
@@ -298,6 +298,8 @@ mod arguments {
let mut out = Vec::new();
let mut t = transport(&mut out, true);
let mut arguments = arguments_v2(["feature-a", "shallow"].iter().copied());
assert!(arguments.is_stateless(true), "V2 is stateless…");
assert!(arguments.is_stateless(false), "…in all cases");

arguments.deepen(1);
arguments.deepen_relative();
8 changes: 8 additions & 0 deletions gix-protocol/tests/fetch/response.rs
Original file line number Diff line number Diff line change
@@ -149,6 +149,14 @@ mod v1 {
async fn all() -> crate::Result {
let (caps, _) = Capabilities::from_bytes(&b"7814e8a05a59c0cf5fb186661d1551c75d1299b5 HEAD\0multi_ack thin-pack filter side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed symref=HEAD:refs/heads/master object-format=sha1 agent=git/2.28.0"[..])?;
let mut args = fetch::Arguments::new(Protocol::V1, Command::Fetch.default_features(Protocol::V1, &caps));
assert!(
args.is_stateless(true /* transport is stateless */),
"V1 is stateless if the transport is connection oriented"
);
assert!(
!args.is_stateless(false /* transport is stateless */),
"otherwise V1 is stateful"
);
assert!(args.can_use_shallow());
assert!(args.can_use_deepen());
assert!(args.can_use_deepen_not());