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, }