feat: source repo chrome from refs/meta/config, dropping worktree metadata
commit
d8a0a60feat: source repo chrome from refs/meta/config, dropping worktree metadata
gather_meta now reads the description, homepage, and topics from the
typed refs/meta/config document instead of the .git/description file
and the tracked HEAD:.gitents/topics blob. This lands the "no worktree
metadata" principle: no .gitents path remains. The homepage surfaces as
a link in the overview About card.
feat: read description/homepage/topics from config in gather_meta
feat: show the configured homepage in the overview About card
Assisted-by: Claude:claude-opus-4-8
Reviews
No reviews of this commit yet — record a verdict below.
Start a review
crates/git-ents/src/config.rs
@@ -22,7 +22,8 @@
pub description: String,
/// The repository's homepage URL; `""` when unset.
pub homepage: String,
- /// The repository's topics (migrated off the tracked `HEAD:.gitents/topics`).
+ /// The repository's topics, members-gated metadata rather than worktree
+ /// content.
pub topics: Vec<String>,
}
crates/git-ents-server/src/web/mod.rs
@@ -24,7 +24,7 @@
use crate::http::{MAX_REPO_DEPTH, is_bare_repo, valid_segment};
use self::assets::{COPY_SCRIPT, FONTS, STYLE};
-use self::git::{discover_repos, git_output, git_output_bytes};
+use self::git::{discover_repos, git_output};
use self::icons::{icon_branch, icon_chevron, icon_folder, icon_logo, icon_repo, icon_search};
/// Render the page for `path`: the repository index at the root, a repository
@@ -97,6 +97,7 @@
rel: String,
branch: Option<String>,
description: Option<String>,
+ homepage: Option<String>,
topics: Vec<String>,
releases: usize,
issues: usize,
@@ -115,20 +116,15 @@
.await
.map(|s| s.trim().to_owned())
.filter(|s| !s.is_empty());
- let description = std::fs::read_to_string(repo.join("description"))
- .ok()
- .map(|s| s.trim().to_owned())
- .filter(|s| !s.is_empty() && !s.starts_with("Unnamed repository"));
- let topics = git_output_bytes(repo, &["cat-file", "-p", "HEAD:.gitents/topics"])
- .await
- .map(|b| {
- String::from_utf8_lossy(&b)
- .split([',', '\n', ' ', '\t'])
- .filter(|s| !s.is_empty())
- .map(str::to_owned)
- .collect()
- })
- .unwrap_or_default();
+ let config = load_config(repo).await.unwrap_or_default();
+ let description = Some(config.description.trim().to_owned()).filter(|s| !s.is_empty());
+ let homepage = Some(config.homepage.trim().to_owned()).filter(|s| !s.is_empty());
+ let topics = config
+ .topics
+ .into_iter()
+ .map(|t| t.trim().to_owned())
+ .filter(|t| !t.is_empty())
+ .collect();
let releases = git_output(repo, &["tag", "--list"])
.await
.map(|s| s.lines().filter(|l| !l.trim().is_empty()).count())
@@ -137,12 +133,22 @@
rel: rel.to_owned(),
branch,
description,
+ homepage,
topics,
releases,
issues: 0,
}
}
+/// Load the repository's `refs/meta/config` document off the async runtime.
+async fn load_config(repo: &Path) -> Option<git_ents::config::Config> {
+ let repo = repo.to_owned();
+ tokio::task::spawn_blocking(move || git_ents::config::load(&repo))
+ .await
+ .ok()?
+ .ok()
+}
+
/// Wrap a repository view in the shared header band and tab bar, then the page
/// shell. `active` highlights the current tab.
fn repo_shell(meta: &RepoMeta, active: Tab, title: &str, body: Markup) -> Markup {
crates/git-ents-server/src/web/pages.rs
@@ -82,6 +82,11 @@
}
div.card {
div.card-header { "About" }
+ @if let Some(homepage) = &meta.homepage {
+ div.aside-row {
+ a href=(homepage) rel="noreferrer" { (homepage) }
+ }
+ }
@if let Some((lang, color, _)) = langs.first() {
div.aside-row {
span.dot style={ "background:" (color) } {}