🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2022-08-30 1:42:22.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2022-08-30 1:54:31.0 +01:00:00
commit
52375c75b823dce9fae1b5b99ee1b22d3e225dd5 [patch]
tree
b6bd3f8847eff5285f539e70cc779c56006cb34e
parent
dbba75aca99ebdfe5c95ce958784d081650b3f3b
download
52375c75b823dce9fae1b5b99ee1b22d3e225dd5.tar.gz

Fix issue with git ignoring some trees and files due to being unsorted



Diff

 chartered-git/src/command_handlers/ls_refs.rs | 2 +-
 chartered-git/src/git/packfile/high_level.rs  | 9 +++++++++
 chartered-git/src/git/packfile/low_level.rs   | 5 +++--
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/chartered-git/src/command_handlers/ls_refs.rs b/chartered-git/src/command_handlers/ls_refs.rs
index d4dee55..34f757b 100644
--- a/chartered-git/src/command_handlers/ls_refs.rs
+++ a/chartered-git/src/command_handlers/ls_refs.rs
@@ -22,7 +22,7 @@
    let commit_hash = hex::encode(&commit_hash);

    handle.write(PktLine::Data(
        format!("{} HEAD symref-target:refs/heads/master\n", commit_hash).as_bytes(),
        format!("{} HEAD symref-target:refs/heads/master", commit_hash).as_bytes(),
    ))?;
    handle.write(PktLine::Flush)?;
    handle.flush(session, channel);
diff --git a/chartered-git/src/git/packfile/high_level.rs b/chartered-git/src/git/packfile/high_level.rs
index b610bd6..0b0d984 100644
--- a/chartered-git/src/git/packfile/high_level.rs
+++ a/chartered-git/src/git/packfile/high_level.rs
@@ -6,6 +6,8 @@
//! for our purposes because `cargo` will `git pull --force` from our Git

//! server, allowing us to ignore any history the client may have.


use std::borrow::Cow;

use arrayvec::ArrayVec;
use indexmap::IndexMap;

@@ -141,11 +143,13 @@
                TreeItem::Blob(hash) => LowLevelTreeItem {
                    kind: TreeItemKind::File,
                    name,
                    sort_name: Cow::Borrowed(name),
                    hash: *hash,
                },
                TreeItem::Tree(tree) => LowLevelTreeItem {
                    kind: TreeItemKind::Directory,
                    name,
                    sort_name: Cow::Owned(format!("{}/", name)),
                    // we're essentially working through our tree from the bottom up,
                    // so we can grab the hash of each directory along the way and
                    // reference it from the parent directory
@@ -153,6 +157,11 @@
                },
            });
        }

        // we need to sort our tree alphabetically, otherwise Git will silently
        // stop parsing the rest of the tree once it comes across an unsorted
        // tree entry.
        tree.sort_unstable_by(|a, b| a.sort_name.cmp(&b.sort_name));

        // gets the hash of the tree we've just worked on, and
        // pushes it to the packfile
diff --git a/chartered-git/src/git/packfile/low_level.rs b/chartered-git/src/git/packfile/low_level.rs
index acfec41..d1cb6f8 100644
--- a/chartered-git/src/git/packfile/low_level.rs
+++ a/chartered-git/src/git/packfile/low_level.rs
@@ -1,10 +1,10 @@
use bytes::{BufMut, BytesMut};
use flate2::{write::ZlibEncoder, Compression};
use sha1::{
    digest::{generic_array::GenericArray, OutputSizeUser},
    Digest, Sha1,
};
use std::{convert::TryInto, fmt::Write, io::Write as IoWrite};
use std::{borrow::Cow, convert::TryInto, fmt::Write, io::Write as IoWrite};

pub type HashOutput = GenericArray<u8, <Sha1 as OutputSizeUser>::OutputSize>; // [u8; 20], but sha-1 returns a GenericArray

@@ -141,10 +141,11 @@
    }
}

#[derive(Debug, Copy, Clone)]
#[derive(Debug, Clone)]
pub struct TreeItem<'a> {
    pub kind: TreeItemKind,
    pub name: &'a str,
    pub sort_name: Cow<'a, str>,
    pub hash: HashOutput,
}