diff --git a/Cargo.lock b/Cargo.lock
@@ -754,6 +754,7 @@ dependencies = [
"humantime",
"owning_ref",
"path-clean",
+ "serde",
"time",
"tokio",
"tower",
diff --git a/Cargo.toml b/Cargo.toml
@@ -14,6 +14,7 @@ git2 = "0.14"
humantime = "2.1"
path-clean = "0.1"
owning_ref = "0.4"
+serde = { version = "1.0", features = ["derive"] }
time = "0.3"
tokio = { version = "1.19", features = ["full"] }
tower = "0.4"
diff --git a/src/git.rs b/src/git.rs
@@ -1,6 +1,6 @@
use std::{borrow::Cow, collections::BTreeMap, fmt::Display, path::Path, time::Duration};
-use git2::{Repository, Signature};
+use git2::{Oid, Repository, Signature};
use owning_ref::OwningHandle;
use time::OffsetDateTime;
@@ -64,6 +64,17 @@ impl Commit {
}
}
+pub fn get_commit(path: &Path, commit: &str) -> Commit {
+ let repo = Repository::open_bare(path).unwrap();
+
+ let commit = OwningHandle::new_with_fn(Box::new(repo), |v| {
+ Box::new(unsafe { (*v).find_commit(Oid::from_str(commit).unwrap()).unwrap() })
+ });
+
+ // TODO: we can cache this
+ Commit(commit)
+}
+
pub fn get_latest_commit(path: &Path) -> Commit {
let repo = Repository::open_bare(path).unwrap();
diff --git a/src/methods/repo.rs b/src/methods/repo.rs
@@ -4,6 +4,7 @@ use std::{
};
use askama::Template;
+use axum::extract::Query;
use axum::{
handler::Handler,
http::Request,
@@ -11,8 +12,10 @@ use axum::{
Extension,
};
use path_clean::PathClean;
+use serde::Deserialize;
use tower::{util::BoxCloneService, Service};
+use crate::git::get_commit;
use crate::{get_latest_commit, git::Commit, layers::UnwrapInfallible};
#[derive(Clone)]
@@ -118,10 +121,16 @@ pub async fn handle_about(Extension(repo): Extension<Repository>) -> Html<String
Html(View { repo }.render().unwrap())
}
+#[derive(Deserialize)]
+pub struct CommitQuery {
+ id: Option<String>,
+}
+
#[allow(clippy::unused_async)]
pub async fn handle_commit(
Extension(repo): Extension<Repository>,
Extension(RepositoryPath(repository_path)): Extension<RepositoryPath>,
+ Query(query): Query<CommitQuery>,
) -> Html<String> {
#[derive(Template)]
#[template(path = "repo/commit.html")]
@@ -133,7 +142,11 @@ pub async fn handle_commit(
Html(
View {
repo,
- commit: get_latest_commit(&repository_path),
+ commit: if let Some(commit) = query.id {
+ get_commit(&repository_path, &commit)
+ } else {
+ get_latest_commit(&repository_path)
+ },
}
.render()
.unwrap(),