wayver's git archive


a simple self-hosted git server
git clone https://git.wayver.dev/bile

Commit: 7e0330303eec590c92eb6194f83f04d0e8fb2ea0 (tree)
Parent: 6e060abc1f25c2e1b79fe06bfa8b72cd26952ee1 (tree)
Author: wayverd
Date: 2026 M02 19, Thu 19:32:05 -0500
4 files changed; 43 insertions 9 deletions
fixed issue where non-directory and dotfiles are treated as git repos

diff --git a/Cargo.lock b/Cargo.lock
index 0380a46..3ec10bd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -311,6 +311,7 @@ dependencies = [
  "tracing",
  "tracing-error",
  "tracing-subscriber",
+ "trim-in-place",
  "two-face",
 ]
 
@@ -2166,6 +2167,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "trim-in-place"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc"
+
+[[package]]
 name = "two-face"
 version = "0.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index f33d8f5..e69c2ce 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -40,6 +40,7 @@ tower-http = { version = "=0.6.8", features = ["timeout", "trace"] }
 tracing = "=0.1.44"
 tracing-error = "=0.2.1"
 tracing-subscriber = { version = "=0.3.22", features = ["env-filter"] }
+trim-in-place = "=0.1.7"
 two-face = { version = "=0.5.1", default-features = false, features = ["syntect-fancy"] }
 
 [profile.release]
diff --git a/src/handlers/index.rs b/src/handlers/index.rs
index af5a9e1..e4b2ff3 100644
--- a/src/handlers/index.rs
+++ b/src/handlers/index.rs
@@ -39,6 +39,19 @@ fn inner(state: &BileState) -> Result<Response> {
 
     for entry in read {
         let entry = entry.context("failed to open directory entry")?;
+        let metadata = entry.metadata().context("failed to get file metadata")?;
+
+        if !metadata.is_dir() {
+            continue;
+        }
+
+        if entry
+            .file_name()
+            .to_str()
+            .is_some_and(|p| p != "." && p.starts_with('.'))
+        {
+            continue;
+        }
 
         let Some(repo) = Repository::open_path(&state.config, &entry.path())
             .context("failed to open repository")?
diff --git a/src/http/extractor.rs b/src/http/extractor.rs
index d674c3f..6399473 100644
--- a/src/http/extractor.rs
+++ b/src/http/extractor.rs
@@ -1,6 +1,7 @@
 use std::fmt;
 
 use serde::de::Error as _;
+use trim_in_place::TrimInPlace as _;
 
 pub(crate) struct Commit(pub String);
 
@@ -15,9 +16,11 @@ impl<'de> serde::Deserialize<'de> for Commit {
     where
         D: serde::Deserializer<'de>,
     {
-        let value = String::deserialize(deserializer)?;
+        let mut value = String::deserialize(deserializer)?;
 
-        if value.is_empty() {
+        value.trim_in_place();
+
+        if value.is_empty() || value.starts_with('.') {
             return Err(D::Error::custom("invalid commit ref"));
         }
 
@@ -44,7 +47,9 @@ impl<'de> serde::Deserialize<'de> for Obj {
     where
         D: serde::Deserializer<'de>,
     {
-        let value = String::deserialize(deserializer)?;
+        let mut value = String::deserialize(deserializer)?;
+
+        value.trim_in_place();
 
         if value.is_empty() {
             return Err(D::Error::custom("invalid object ref"));
@@ -67,7 +72,9 @@ impl<'de> serde::Deserialize<'de> for ObjectName {
     where
         D: serde::Deserializer<'de>,
     {
-        let value = String::deserialize(deserializer)?;
+        let mut value = String::deserialize(deserializer)?;
+
+        value.trim_in_place();
 
         if value.is_empty() {
             return Err(D::Error::custom("invalid object name"));
@@ -90,9 +97,11 @@ impl<'de> serde::Deserialize<'de> for Ref {
     where
         D: serde::Deserializer<'de>,
     {
-        let value = String::deserialize(deserializer)?;
+        let mut value = String::deserialize(deserializer)?;
 
-        if value.is_empty() {
+        value.trim_in_place();
+
+        if value.is_empty() || value.starts_with('.') {
             return Err(D::Error::custom("invalid ref"));
         }
 
@@ -113,9 +122,11 @@ impl<'de> serde::Deserialize<'de> for RepoName {
     where
         D: serde::Deserializer<'de>,
     {
-        let value = String::deserialize(deserializer)?;
+        let mut value = String::deserialize(deserializer)?;
 
-        if value.is_empty() {
+        value.trim_in_place();
+
+        if value.is_empty() || value.starts_with('.') {
             return Err(D::Error::custom("invalid repo name"));
         }
 
@@ -136,7 +147,9 @@ impl<'de> serde::Deserialize<'de> for Tag {
     where
         D: serde::Deserializer<'de>,
     {
-        let value = String::deserialize(deserializer)?;
+        let mut value = String::deserialize(deserializer)?;
+
+        value.trim_in_place();
 
         if value.is_empty() {
             return Err(D::Error::custom("invalid tag"));