don't
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: align `sh.tangled.repo.{branch,branches}` impl with upstream

Signed-off-by: tjh <x@tjh.dev>

tjh 37da73e1 8be780c7

+27 -5
+2 -2
crates/gordian-knot/README.md
··· 14 14 | ✅ | `sh.tangled.knot.version` | | 15 15 | ✅ | `sh.tangled.repo.archive` | | 16 16 | ✅ | `sh.tangled.repo.blob` | | 17 - | ✅ | `sh.tangled.repo.branch` | Ignores `shortHash` parameter | 17 + | ✅ | `sh.tangled.repo.branch` | | 18 18 | ✅ | `sh.tangled.repo.branches` | | 19 19 | ✅ | `sh.tangled.repo.create` | | 20 20 | ✅ | `sh.tangled.repo.delete` | | ··· 23 23 | ✅ | `sh.tangled.repo.mergeCheck` | | 24 24 | ✅ | `sh.tangled.repo.log` | | 25 25 | ✅ | `sh.tangled.repo.setDefaultBranch` | | 26 - | ✅ | `sh.tangled.repo.tag` | Ignores redundant `message` parameter | 26 + | ✅ | `sh.tangled.repo.tag` | | 27 27 | ✅ | `sh.tangled.repo.tags` | | 28 28 | 🔶 | `sh.tangled.repo.compare` | Seems to work, but only computes `patch` field 😅 | 29 29 | 🔶 | `sh.tangled.repo.tree` | Cheats by not computing most recent commit 🚀 |
+6 -1
crates/gordian-knot/src/public/xrpc/sh_tangled/repo/branch.rs
··· 1 1 use axum::Json; 2 2 3 3 use crate::extract::repository::XrpcRepository; 4 + use crate::lexicon::extra::objectid::ObjectId; 4 5 use crate::lexicon::sh_tangled::repo::branch::Input; 5 6 use crate::lexicon::sh_tangled::repo::branch::Output; 6 7 use crate::model::convert; ··· 12 11 use crate::public::xrpc::XrpcResult; 13 12 14 13 pub const LXM: &str = "/sh.tangled.repo.branch"; 14 + 15 + const SHORT_HASH_LEN: usize = 7; 15 16 16 17 #[tracing::instrument(target = "sh_tangled::repo::branch", err)] 17 18 pub async fn handle( ··· 29 26 30 27 let commit = reference.peel_to_commit().map_err(RefNotFound)?; 31 28 let name = reference.name().shorten().to_string(); 32 - let hash = commit.id.into(); 29 + let hash: ObjectId = commit.id.into(); 33 30 let time = commit 34 31 .committer() 35 32 .map_err(RepoError)? ··· 50 47 .to_string(); 51 48 52 49 let is_default = default_name == name; 50 + let short_hash = hash.to_hex_with_len(SHORT_HASH_LEN).to_string(); 53 51 54 52 Ok(Json(Output { 55 53 name, 56 54 hash, 55 + short_hash, 57 56 when, 58 57 author, 59 58 message,
+9
crates/gordian-lexicon/src/extra/objectid.rs
··· 1 1 use core::fmt; 2 2 use std::marker::PhantomData; 3 + use std::ops; 3 4 use std::str::FromStr; 4 5 5 6 use serde::Deserialize; ··· 28 27 #[must_use] 29 28 pub const fn id(&self) -> gix_hash::ObjectId { 30 29 self.inner 30 + } 31 + } 32 + 33 + impl ops::Deref for ObjectId { 34 + type Target = gix_hash::ObjectId; 35 + 36 + fn deref(&self) -> &Self::Target { 37 + &self.inner 31 38 } 32 39 } 33 40
+10 -2
crates/gordian-lexicon/src/sh_tangled/repo/branch.rs
··· 20 20 pub name: String, 21 21 } 22 22 23 - #[derive(Debug, Serialize)] 24 - #[serde(rename_all = "camelCase")] 23 + #[derive(Debug, Deserialize, Serialize)] 24 + #[serde(deny_unknown_fields, rename_all = "camelCase")] 25 25 pub struct Output { 26 26 /// Branch name. 27 27 pub name: String, 28 28 29 29 /// Latest commit hash on this branch. 30 30 pub hash: ObjectId, 31 + 32 + pub short_hash: String, 31 33 32 34 /// Timestamp of the latest commit. 33 35 #[serde(with = "time::serde::rfc3339")] ··· 42 40 43 41 /// Whether this is the default branch 44 42 pub is_default: bool, 43 + } 44 + 45 + #[test] 46 + fn can_deserialize() { 47 + const SAMPLE1: &str = r#"{"author":{"email":"did:plc:3fwecdnvtcscjnrx2p4n7alz","name":"Lewis","when":"2026-03-05T13:28:08+02:00"},"hash":"e326cc53ad4e9123552bdf20a192aff6ca1eb135","isDefault":true,"message":"appview/oauth: recover from corrupted session cookies on login\n","name":"master","shortHash":"e326cc5","when":"2026-03-05T13:28:08+02:00"}"#; 48 + let _: Output = serde_json::from_str(SAMPLE1).unwrap(); 45 49 }