🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2021-08-30 2:05:28.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-08-30 2:05:28.0 +01:00:00
commit
bbbde41699d81968662685bda1bf657b92c4f408 [patch]
tree
6ada73d1051c0f59d8a1ba147ae6a0558ebb5d9f
parent
f6046cf6372e0d8ab845f6dec1602c303a66ee91
download
bbbde41699d81968662685bda1bf657b92c4f408.tar.gz

git no longer erroring when pulling



Diff

 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::<u32>() + std::mem::size_of::<u32>()
    }

    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
        {