From bbbde41699d81968662685bda1bf657b92c4f408 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Mon, 30 Aug 2021 02:05:28 +0100 Subject: [PATCH] git no longer erroring when pulling --- src/main.rs | 38 ++++++++++++++++++++++++++++++++------ src/git/packfile.rs | 25 +++++++++++++++++++------ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/main.rs b/src/main.rs index 019fc61..03b6e7f 100644 --- a/src/main.rs +++ a/src/main.rs @@ -1,8 +1,9 @@ pub mod git; use crate::git::PktLine; use bytes::BytesMut; +use bytes::BufMut; use futures::future::Future; use git::codec::Encoder; use git::codec::GitCodec; @@ -141,6 +142,7 @@ Box::pin(async move { let mut ls_refs = false; let mut fetch = false; + let mut done = false; while let Some(frame) = self.codec.decode(&mut self.input_bytes)? { eprintln!("data: {:x?}", frame); @@ -149,13 +151,15 @@ ls_refs = true; } else if frame.as_ref() == "command=fetch".as_bytes() { fetch = true; + } else if frame.as_ref() == "done".as_bytes() { + done = true; } } // echo -ne "0014command=ls-refs\n0014agent=git/2.321\n00010008peel000bsymrefs000aunborn0014ref-prefix HEAD\n0000" // GIT_PROTOCOL=version=2 ssh -o SendEnv=GIT_PROTOCOL git@github.com git-upload-pack '/w4/chartered.git' // ''.join([('{:04x}'.format(len(v) + 5)), v, "\n"]) - // echo -ne "0012command=fetch\n0001000ethin-pack\n0010no-progress\n0010include-tag\n000eofs-delta\n0032want 1a1b25ae7c87a0e87b7a9aa478a6bc4331c6b954\n0009done\n" + // echo -ne "0012command=fetch\n0001000ethin-pack\n0010no-progress\n0010include-tag\n000eofs-delta\n0032want f6046cf6372e0d8ab845f6dec1602c303a66ee91\n" // sends a 000dpackfile back // https://shafiul.github.io/gitbook/7_the_packfile.html if ls_refs { @@ -165,22 +169,36 @@ } if fetch { + self.write(PktLine::Data(b"acknowledgments\n"))?; + self.write(PktLine::Data(b"ready\n"))?; + self.write(PktLine::Delimiter)?; + // self.write(PktLine::Data(b"shallow-info\n"))?; + // self.write(PktLine::Data(b"unshallow\n"))?; + done = true; + } + + if done { + self.write(PktLine::Data(b"packfile\n"))?; + let packfile = git::packfile::PackFile::new(vec![git::packfile::PackFileEntry::new( git::packfile::PackFileEntryType::Blob, - b"testing this is a test cool test", + b"testing this is a test cool test!", )?]); - { - let mut buf = BytesMut::new(); - let packfile_index = git::packfile::PackFileIndex { - packfile: &packfile, - }; - packfile_index.encode_to(&mut buf)?; - self.write(PktLine::Data(buf.as_ref()))?; - } + // { + // let mut buf = BytesMut::new(); + // buf.put_u8(1); + // git::packfile::PackFileIndex { + // packfile: &packfile, + // } + // .encode_to(&mut buf)?; + // self.write(PktLine::Data(buf.as_ref()))?; + // self.write(PktLine::Flush)?; + // } { let mut buf = BytesMut::new(); + buf.put_u8(1); packfile.encode_to(&mut buf)?; self.write(PktLine::Data(buf.as_ref()))?; } diff --git a/src/git/packfile.rs b/src/git/packfile.rs index 668a2ad..cdb78f9 100644 --- a/src/git/packfile.rs +++ a/src/git/packfile.rs @@ -1,8 +1,9 @@ use bytes::{BufMut, BytesMut}; use const_sha1::{sha1, ConstBuffer}; use flate2::{write::ZlibEncoder, Compression}; use std::convert::TryInto; use std::io::Write as IoWrite; +use sha1::{Sha1, Digest}; // The offset/sha1[] tables are sorted by sha1[] values (this is to // allow binary search of this table), and fanout[] table points at @@ -15,13 +16,11 @@ impl<'a> PackFileIndex<'a> { pub fn encode_to(self, original_buf: &mut BytesMut) -> Result<(), anyhow::Error> { - use sha1::{Sha1, Digest}; - // split the buffer so we can hash only what we're currently generating at the // end of this function - let mut buf = original_buf.split(); + let mut buf = original_buf.split_off(original_buf.len()); - buf.extend_from_slice(&[255u8, 116u8, 79u8, 99u8]); // magic header + buf.extend_from_slice(b"\xfftOc"); // magic header buf.put_u32(2); // version // calculate total `PackFileEntry` hashes beginning with the same first byte @@ -113,18 +112,22 @@ pub const fn header_size() -> usize { 4 + std::mem::size_of::() + std::mem::size_of::() } + + pub fn encode_to(&self, original_buf: &mut BytesMut) -> Result<(), anyhow::Error> { + let mut buf = original_buf.split_off(original_buf.len()); - pub fn encode_to(self, buf: &mut BytesMut) -> Result<(), anyhow::Error> { buf.extend_from_slice(b"PACK"); // magic header buf.put_u32(2); // version buf.put_u32(self.entries.len().try_into().unwrap()); // number of entries in the packfile for entry in &self.entries { - entry.encode_to(buf)?; + entry.encode_to(&mut buf)?; } - buf.extend_from_slice(&self.hash); + buf.extend_from_slice(&sha1::Sha1::digest(&buf[..])); + original_buf.unsplit(buf); + Ok(()) } } @@ -191,9 +194,9 @@ }) } - fn size_of_data_be(&self) -> usize { - self.uncompressed_size.to_be() - } + // fn size_of_data_be(&self) -> usize { + // self.uncompressed_size.to_be() + // } // The object header is a series of one or more 1 byte (8 bit) hunks // that specify the type of object the following data is, and the size @@ -203,7 +206,7 @@ // byte, otherwise the data starts next. The first 3 bits in the first // byte specifies the type of data, according to the table below. fn write_header(&self, buf: &mut BytesMut) { - let mut size = self.size_of_data_be(); + let mut size = self.uncompressed_size; // write header { -- rgit 0.1.3