🏡 index : ~doyle/gitlab-cargo-shim.git

author Jordan Doyle <jordan@doyle.la> 2022-03-13 17:15:26.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2022-03-13 17:15:26.0 +00:00:00
commit
3fe9872e4320217bcc8b353460c8d9bd063e668b [patch]
tree
a70387240eb0a15b1e9d918a35dc31e361c22319
parent
be1b834ed9718c36bf26af3e6ffe69a731823ed1
download
3fe9872e4320217bcc8b353460c8d9bd063e668b.tar.gz

Sort tree before inserting into packfile



Diff

 src/main.rs                         | 11 ++++++++++-
 src/git_command_handlers/ls_refs.rs |  2 +-
 src/protocol/high_level.rs          |  7 +++++++
 src/protocol/low_level.rs           |  1 +
 4 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index a9d07cd..772f5e3 100644
--- a/src/main.rs
+++ a/src/main.rs
@@ -24,6 +24,7 @@
use bytes::{BufMut, Bytes, BytesMut};
use clap::Parser;
use futures::Future;
use indexmap::IndexMap;
use parking_lot::RwLock;
use std::{
    borrow::Cow, collections::HashMap, fmt::Write, net::SocketAddr, net::SocketAddrV6, pin::Pin,
@@ -35,7 +36,7 @@
};
use thrussh_keys::key::PublicKey;
use tokio_util::{codec::Decoder, codec::Encoder as CodecEncoder};
use tracing::{error, info, info_span, Instrument, Span};
use tracing::{debug, error, info, info_span, Instrument, Span};
use uuid::Uuid;

const AGENT: &str = concat!(
@@ -110,6 +111,8 @@

struct Server<U: UserProvider + PackageProvider + Send + Sync + 'static> {
    gitlab: Arc<U>,
    // todo: we could make our commit hash stable by leaving an update time
    //  in this cache and using that as our commit time
    metadata_cache: MetadataCache,
}

@@ -184,11 +187,11 @@
    /// and groups them by crate.

    async fn fetch_releases_by_crate(
        &self,
    ) -> anyhow::Result<HashMap<(U::CratePath, String), Vec<Release>>> {
    ) -> anyhow::Result<IndexMap<(U::CratePath, String), Vec<Release>>> {
        let user = self.user()?;
        let group = self.group()?;

        let mut res = HashMap::new();
        let mut res = IndexMap::new();

        for (path, release) in Arc::clone(&self.gitlab)
            .fetch_releases_for_group(group, user)
@@ -296,6 +299,8 @@
            for release in releases {
                let checksum = &release.checksum;
                let version = &release.version;

                debug!("Fetching metadata for {}-{}", crate_name, version);

                // parses the `cargo metadata` stored in the release, which
                // should be stored under `metadata.json`.
diff --git a/src/git_command_handlers/ls_refs.rs b/src/git_command_handlers/ls_refs.rs
index 4b77740..3c67aa6 100644
--- a/src/git_command_handlers/ls_refs.rs
+++ a/src/git_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/src/protocol/high_level.rs b/src/protocol/high_level.rs
index 917b065..e7dae0d 100644
--- a/src/protocol/high_level.rs
+++ a/src/protocol/high_level.rs
@@ -132,11 +132,13 @@
            tree.push(match *item {
                TreeItem::Blob(hash) => LowLevelTreeItem {
                    kind: TreeItemKind::File,
                    sort_name: name.clone(),
                    name,
                    hash,
                },
                TreeItem::Tree(tree) => LowLevelTreeItem {
                    kind: TreeItemKind::Directory,
                    sort_name: format!("{}/", name),
                    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
@@ -145,6 +147,11 @@
                },
            });
        }

        // we need to sort our tree alphabetically, otherwise Git will silently
        // stop parsing the rest of the tree once it comes across a non-sorted
        // 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/src/protocol/low_level.rs b/src/protocol/low_level.rs
index 1365b27..b013cb8 100644
--- a/src/protocol/low_level.rs
+++ a/src/protocol/low_level.rs
@@ -143,6 +143,7 @@
    pub kind: TreeItemKind,
    pub name: String,
    pub hash: HashOutput,
    pub sort_name: String,
}

// `[mode] [name]\0[hash]`