Skip to content

Commit 42356ab

Browse files
committed
Merge branch 'push-support'
2 parents 0c9c48b + 4d84a20 commit 42356ab

File tree

6 files changed

+90
-0
lines changed

6 files changed

+90
-0
lines changed

DEVELOPMENT.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ This also means that CI may fail despite everything being alright locally, and t
213213

214214
## How to update fixtures
215215

216+
### For object data
217+
216218
Fixtures are created by using a line like this which produces a line we ignore via `tail +1` followed by the un-prettified object payload
217219
trailed by a newline.
218220
```sh

git-transport/src/client/async_io/request.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,12 @@ impl<'a> RequestWriter<'a> {
8484
self.write_message(self.on_into_read).await?;
8585
Ok(self.reader)
8686
}
87+
88+
/// Dissolve this instance into its write and read handles without any side-effect.
89+
///
90+
/// This is useful to take more over when to write with packetline or not, which is why the writer doesn't write
91+
/// packetlines but verbatim.
92+
pub fn into_parts(self) -> (Box<dyn AsyncWrite + Unpin + 'a>, Box<dyn ExtendedBufRead + Unpin + 'a>) {
93+
(self.writer.into_inner(), self.reader)
94+
}
8795
}

git-transport/src/client/blocking_io/request.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,12 @@ impl<'a> RequestWriter<'a> {
6060
self.write_message(self.on_into_read)?;
6161
Ok(self.reader)
6262
}
63+
64+
/// Dissolve this instance into its write and read handles without any side-effect.
65+
///
66+
/// This is useful to take more over when to write with packetline or not, which is why the writer doesn't write
67+
/// packetlines but verbatim.
68+
pub fn into_parts(self) -> (Box<dyn io::Write + 'a>, Box<dyn ExtendedBufRead + Unpin + 'a>) {
69+
(self.writer.into_inner(), self.reader)
70+
}
6371
}

git-transport/tests/client/git.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,70 @@ async fn handshake_v1_and_request() -> crate::Result {
145145
Ok(())
146146
}
147147

148+
#[maybe_async::test(feature = "blocking-client", async(feature = "async-client", async_std::test))]
149+
async fn push_v1_simulated() -> crate::Result {
150+
let mut out = Vec::new();
151+
let server_response = fixture_bytes("v1/push.response");
152+
let mut c = git::Connection::new(
153+
server_response.as_slice(),
154+
&mut out,
155+
Protocol::V1,
156+
"/foo.git",
157+
Some(("example.org", None)),
158+
git::ConnectMode::Process,
159+
);
160+
161+
let mut writer = c.request(client::WriteMode::Binary, client::MessageKind::Flush)?;
162+
let expected = fixture_bytes("v1/push.request");
163+
writer.write_all(b"7c09ba0c4c3680af369bda4fc8e3c58d3fccdc76 32690d87d3943c7c0dda81246d0cde344ca7e633 refs/heads/main\0 report-status-v2 side-band-64k object-format=sha1 agent=git/2.37.1.(Apple.Git-137.1)").await?;
164+
writer.write_message(client::MessageKind::Flush).await?;
165+
{
166+
let (mut write, mut read) = writer.into_parts();
167+
write.write_all(&expected[191..]).await?;
168+
169+
let messages = Arc::new(Mutex::new(Vec::<String>::new()));
170+
read.set_progress_handler(Some(Box::new({
171+
let sb = messages.clone();
172+
move |is_err, data| {
173+
assert!(!is_err);
174+
sb.deref()
175+
.lock()
176+
.expect("no panic in other threads")
177+
.push(std::str::from_utf8(data).expect("valid utf8").to_owned())
178+
}
179+
})));
180+
let mut lines = read.lines();
181+
let mut info = Vec::new();
182+
#[allow(clippy::while_let_on_iterator)] // needed in async version of test
183+
while let Some(line) = lines.next().await {
184+
info.push(line?)
185+
}
186+
assert_eq!(
187+
info,
188+
&["000eunpack ok", "0017ok refs/heads/main", "0000"],
189+
"this seems to be a packetline encoding within a packetline encoding! Including a flush package. Strange, but it's the real deal."
190+
);
191+
let expected_progress = &["Resolving deltas: 0% (0/2)\r",
192+
"Resolving deltas: 50% (1/2)\r",
193+
"Resolving deltas: 100% (2/2)\r",
194+
"Resolving deltas: 100% (2/2), completed with 2 local objects.",
195+
"\nGitHub found 1 vulnerability on the-lean-crate/criner's default branch (1 high). To find out more, visit:\n https://github.com/the-lean-crate/criner/security/dependabot/1\n"
196+
];
197+
assert_eq!(
198+
messages.lock().expect("no poison").as_slice(),
199+
expected_progress,
200+
"these look like they are created once the whole pack has been received"
201+
);
202+
}
203+
204+
assert_eq!(
205+
out.as_slice().as_bstr(),
206+
expected.as_bstr(),
207+
"we are able to reproduce a typical push request by hand with a little bit of juggling"
208+
);
209+
Ok(())
210+
}
211+
148212
#[maybe_async::test(feature = "blocking-client", async(feature = "async-client", async_std::test))]
149213
async fn handshake_v1_process_mode() -> crate::Result {
150214
let mut out = Vec::new();
1.36 KB
Binary file not shown.

git-transport/tests/fixtures/v1/push.response

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
0022Resolving deltas: 0% (0/2)0022Resolving deltas: 50% (1/2)0022Resolving deltas: 100% (2/2)0043Resolving deltas: 100% (2/2), completed with 2 local objects.
2+
0013000eunpack ok
3+
001c0017ok refs/heads/main
4+
00b5
5+
GitHub found 1 vulnerability on the-lean-crate/criner's default branch (1 high). To find out more, visit:
6+
https://github.com/the-lean-crate/criner/security/dependabot/1
7+
8+
000900000000

0 commit comments

Comments
 (0)