rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 heartwood2dfe90755d20b4a4d02494c7e42478aadf284443
{
"request": "trigger",
"version": 1,
"event_type": "patch",
"repository": {
"id": "rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5",
"name": "heartwood",
"description": "Radicle Heartwood Protocol & Stack",
"private": false,
"default_branch": "master",
"delegates": [
"did:key:z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT",
"did:key:z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW",
"did:key:z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM",
"did:key:z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz",
"did:key:z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz"
]
},
"action": "Created",
"patch": {
"id": "1e96844aef957e27206a8e3d87fbd4706890b174",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"title": "cli: use git config's `core.abbrev` for SHA-1 abbrevs",
"state": {
"status": "archived",
"conflicts": []
},
"before": "ee1c867800eacea37d489d966622d0aff0af0b70",
"after": "2dfe90755d20b4a4d02494c7e42478aadf284443",
"commits": [
"2dfe90755d20b4a4d02494c7e42478aadf284443",
"b2c7d87a1c90e826e415bdced04d9136e343151d"
],
"target": "6cfed884bf37cba1e0d8e97fa8b0e94df4a04b1f",
"labels": [],
"assignees": [],
"revisions": [
{
"id": "1e96844aef957e27206a8e3d87fbd4706890b174",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "Implements `radicle_cli::git::get_abbrev()`, which will\nget git's `core.abbrev`, which can be applied to COB IDs\nand git OIDs (or any SHA1 abbreviation.)\n\nThis also respects special cases where `core.abbrev` can \nbe legally set to \"auto\" or \"no\", where \"auto\" gets an appropriate\nlength based on a loose count of objects in the current repo, and \n\"no\" which doesn't abbreviate the SHA1 at all.",
"base": "bb5355fcb1a47e6a6ac3e441e2b807906d7ef135",
"oid": "1c20d56d3a963ea1a195b84fd50ad53926a995fe",
"timestamp": 1714434648
},
{
"id": "7a9bd356c9e701a609c7172f86a8b7141579c75e",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "Default to \"auto\" on config/entry failure\nchange CONFIG_ABBRED_DEFAULT to 10",
"base": "bb5355fcb1a47e6a6ac3e441e2b807906d7ef135",
"oid": "f82e6a8024315c79af9229ab0a3c97ad6c3edffa",
"timestamp": 1715213525
},
{
"id": "bdfee1ca83de7ad9160f5133cfe6c94c20ec9b6a",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "forgot to squash commits. whoops.",
"base": "bb5355fcb1a47e6a6ac3e441e2b807906d7ef135",
"oid": "24a3fffbe7ef815efb1f7248dd402765466daa25",
"timestamp": 1715213734
},
{
"id": "cac8ecbdd90c78faf7e8e148ead87e49ad8fe683",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "Updates this patch to do the following:\n\n - Use `std::sync::OnceLock` as a replacement for `static mut`\n - its actually in the std lib for rust as of 1.70.0, \n see `https://github.com/rust-lang/rust/pull/105587`\n - the `once_cell` crate could prolly be removed as a dep in favor of this but im not\n sure if there are other uses of this dep that aren't covered in the std impl\n\n - `CONFIG_ABBREV_DEFAULT` is now set to 10\n - Will use the local config first (if it can be found) and uses the global config otherwise\n should the local config not be found\n - Upon failing to obtain the local config, global config, or just the `core.abbrev` value,\n will simply default to \"auto\". If that also fails: `CONFIG_ABBREV_DEFAULT`.",
"base": "bb5355fcb1a47e6a6ac3e441e2b807906d7ef135",
"oid": "8e8c98e387e1a8da671f955b4fb197f4c52bc61b",
"timestamp": 1715791662
},
{
"id": "bab1f829df649df9cfb8589e1b0be8167f3589c4",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "Changes:\n- Introduce Abbreviation type to make code clearer\n- Use `CONFIG_ABBREV_DEFAULT` for default cases where any values are missing\n- Make `7` the default value to ensure tests still pass",
"base": "bb5355fcb1a47e6a6ac3e441e2b807906d7ef135",
"oid": "46ae3ae4fe035fffb3847f5c220d43ed2658ac40",
"timestamp": 1718632624
},
{
"id": "189de2faa8fcd9bbaff1aaac48459b905c544e57",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "Changes:\n- Improve `Config` search\n- Add more constants to use\n- Improve commit message",
"base": "bb5355fcb1a47e6a6ac3e441e2b807906d7ef135",
"oid": "13d8a81ee74bf71c653146762875775335573ce8",
"timestamp": 1718643204
},
{
"id": "276bf662680bff506d6c2a8001358447c940a9ef",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "Rebase",
"base": "765fc48c8496b35717a53405d745b154fc655955",
"oid": "a1d5825f4f08a9973c88b76472eb0a65f7b559f6",
"timestamp": 1719245165
},
{
"id": "38b88d52303469c7cd192e7af42762c5b932df27",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "- Privatized and Added documentation for `CONFIG_ABBREV` and `CONFIG_ABBREV_DEFAULT`\n - Use `OnceLock::get_or_init()` for `get_abbrev()` rather than a `match`",
"base": "765fc48c8496b35717a53405d745b154fc655955",
"oid": "ec048f417a2c28cde57061af3a8c7846ca512786",
"timestamp": 1720528633
},
{
"id": "6e2a988f903233417a4e2e49b5a9ad99b6e7d748",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "- partially implement per-repo abbreviating\n\nMeant to address a key point in review in its respective zulip topic.\nI want to focus on the implementation of `get_abbrev_rid()` and whatnot\nbefore I can go ahead with replacing the old (cwd) implementation with\nthe new one and make it work with all usages of `format::cob()/oid()`.",
"base": "765fc48c8496b35717a53405d745b154fc655955",
"oid": "b5dff552c64cabde688d24b20a8bb9047c27fe62",
"timestamp": 1721933028
},
{
"id": "13d597c8c12a09e6f76dd3a03239d3ab63a1e03f",
"author": {
"id": "did:key:z6Mktnv1oLyUHMHm7j3p5D119V2yRWPrfMXAn3W42irs8DHL",
"alias": "radsammyt"
},
"description": "Rebase.",
"base": "ee1c867800eacea37d489d966622d0aff0af0b70",
"oid": "2dfe90755d20b4a4d02494c7e42478aadf284443",
"timestamp": 1722258773
}
]
}
}
{
"response": "triggered",
"run_id": {
"id": "d42540e2-c725-48bb-8e7c-b4d327ea055f"
},
"info_url": "https://cci.rad.levitte.org//d42540e2-c725-48bb-8e7c-b4d327ea055f.html"
}
Started at: 2025-10-21 20:20:35.226124+02:00
Commands:
$ rad clone rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5 .
✓ Creating checkout in ./...
✓ Remote cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT added
✓ Remote-tracking branch cloudhead@z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT/master created for z6MksFqXN3Yhqk8pTJdUGLwATkRfQvwZXPqR2qMEhbS9wzpT
✓ Remote cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW added
✓ Remote-tracking branch cloudhead@z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW/master created for z6MktaNvN1KVFMkSRAiN4qK5yvX1zuEEaseeX5sffhzPZRZW
✓ Remote fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM added
✓ Remote-tracking branch fintohaps@z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM/master created for z6MkireRatUThvd3qzfKht1S44wpm4FEWSSa4PRMTSQZ3voM
✓ Remote erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz added
✓ Remote-tracking branch erikli@z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz/master created for z6MkgFq6z5fkF2hioLLSNu1zP2qEL1aHXHZzGH1FLFGAnBGz
✓ Remote lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz added
✓ Remote-tracking branch lorenz@z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz/master created for z6MkkPvBfjP4bQmco5Dm7UGsX2ruDBieEHi8n9DVJWX5sTEz
✓ Repository successfully cloned under /opt/radcis/ci.rad.levitte.org/cci/state/d42540e2-c725-48bb-8e7c-b4d327ea055f/w/
╭────────────────────────────────────╮
│ heartwood │
│ Radicle Heartwood Protocol & Stack │
│ 125 issues · 15 patches │
╰────────────────────────────────────╯
Run `cd ./.` to go to the repository directory.
Exit code: 0
$ rad patch checkout 1e96844aef957e27206a8e3d87fbd4706890b174
✓ Switched to branch patch/1e96844 at revision 13d597c
✓ Branch patch/1e96844 setup to track rad/patches/1e96844aef957e27206a8e3d87fbd4706890b174
Exit code: 0
$ git config advice.detachedHead false
Exit code: 0
$ git checkout 2dfe90755d20b4a4d02494c7e42478aadf284443
HEAD is now at 2dfe9075 implement per-repo abbreviating
Exit code: 0
$ git show 2dfe90755d20b4a4d02494c7e42478aadf284443
commit 2dfe90755d20b4a4d02494c7e42478aadf284443
Author: RadsammyT <radsammyt@gmail.com>
Date: Thu Jul 25 14:34:16 2024 -0400
implement per-repo abbreviating
Meant to address a key point in review.
I want to focus on the implementation of `get_abbrev_rid()` and whatnot
before I can go ahead with replacing the old (cwd) implementation with
the new one and make it work with all usages of `format::cob()/oid()`
diff --git a/radicle-cli/src/git.rs b/radicle-cli/src/git.rs
index a93d0d9c..13431a78 100644
--- a/radicle-cli/src/git.rs
+++ b/radicle-cli/src/git.rs
@@ -4,9 +4,11 @@ pub mod ddiff;
pub mod pretty_diff;
pub mod unified_diff;
-use std::collections::HashSet;
+use std::cell::RefCell;
+use std::collections::{HashMap, HashSet};
use std::fmt::Display;
use std::fs::{File, OpenOptions};
+
use std::io;
use std::io::Write;
use std::num::ParseIntError;
@@ -18,14 +20,15 @@ use std::sync::OnceLock;
use anyhow::anyhow;
use anyhow::Context as _;
+use radicle::storage::{ReadRepository, ReadStorage};
use thiserror::Error;
use radicle::crypto::ssh;
-use radicle::git;
use radicle::git::raw as git2;
use radicle::git::{Version, VERSION_REQUIRED};
use radicle::prelude::{NodeId, RepoId};
use radicle::storage::git::transport;
+use radicle::{git, Profile};
pub use radicle::git::raw::{
build::CheckoutBuilder, AnnotatedCommit, Commit, Direction, ErrorCode, MergeAnalysis,
@@ -46,6 +49,10 @@ const CONFIG_ABBREV_DEFAULT: usize = 7;
/// [`get_abbrev()`] should be called to get (or initialize) this value.
static CONFIG_ABBREV: OnceLock<usize> = OnceLock::new();
+thread_local! {
+ /// Stores the Abbreviation size per RID for caching purposes
+ static REPO_ABBREVS: RefCell<HashMap<RepoId, usize>> = RefCell::default();
+}
/// Git revision parameter. Supports extended SHA-1 syntax.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Rev(String);
@@ -432,9 +439,9 @@ impl Abbreviation {
/// In the case of `Abbreviation::Auto`, the `git` CLI is used to determine
/// the shortest abbreviation length to use, if this fails a default of
/// [`CONFIG_ABBREV_DEFAULT`] is returned.
- pub fn length(&self) -> usize {
+ pub fn length(&self, path: &Path) -> usize {
match self {
- Abbreviation::Auto => git(Path::new("."), ["rev-parse", "--short", "HEAD"])
+ Abbreviation::Auto => git(Path::new(path), ["rev-parse", "--short", "HEAD"])
.unwrap_or("a".repeat(CONFIG_ABBREV_DEFAULT))
.trim()
.len(),
@@ -451,10 +458,46 @@ impl Abbreviation {
/// for more details).
///
/// [coreabbrev]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreabbrev
-pub fn get_abbrev() -> usize {
+pub fn get_abbrev_cwd() -> usize {
*OnceLock::get_or_init(&CONFIG_ABBREV, || {
let abbrev = Abbreviation::new().unwrap_or_default();
- abbrev.length()
+ abbrev.length(Path::new("."))
+ })
+}
+
+/// Get the path to the stored repo based off of the provided RID.
+fn get_storage_repo(rid: &RepoId) -> anyhow::Result<PathBuf> {
+ let storage = Profile::load()?.storage;
+ let candidate = storage
+ .repositories()?
+ .into_iter()
+ .find(|x| x.rid == *rid)
+ .ok_or_else(|| anyhow!("Repo not found"))?;
+ let repo = storage.repository(candidate.rid)?;
+ Ok(repo.path().to_path_buf())
+}
+
+/// Get the abbreviation length to use for a specific repository (based off an RID)
+/// for Git SHA formatting.
+///
+/// Only the global Git config is used to lookup [`core.abbrev`][coreabbrev], as this uses
+/// the repositories in storage to determine the amount of characters to abbreviate to.
+///
+/// [coreabbrev]: https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreabbrev
+pub fn get_abbrev_rid(rid: &RepoId) -> usize {
+ REPO_ABBREVS.with_borrow_mut(|map| {
+ if let Some(abbrev) = map.get(rid) {
+ return *abbrev;
+ }
+ let path = match get_storage_repo(rid) {
+ Ok(pb) => pb,
+ Err(_) => return CONFIG_ABBREV_DEFAULT,
+ };
+ let abbrev = Abbreviation::from_global()
+ .unwrap_or_default()
+ .length(&path);
+ map.insert(*rid, abbrev);
+ abbrev
})
}
@@ -475,7 +518,7 @@ pub fn view_diff(
let workdir = repo
.workdir()
.ok_or_else(|| anyhow!("Could not get workdir current repository."))?;
- let abbrev = get_abbrev();
+ let abbrev = get_abbrev_cwd();
let left = format!("{:.abbrev$}", left.to_string());
let right = format!("{:.abbrev$}", right.to_string());
diff --git a/radicle-cli/src/terminal/format.rs b/radicle-cli/src/terminal/format.rs
index 1bacb17b..8f210152 100644
--- a/radicle-cli/src/terminal/format.rs
+++ b/radicle-cli/src/terminal/format.rs
@@ -6,7 +6,7 @@ pub use radicle_term::format::*;
pub use radicle_term::{style, Paint};
use radicle::cob::ObjectId;
-use radicle::identity::Visibility;
+use radicle::identity::{RepoId, Visibility};
use radicle::node::policy::Policy;
use radicle::node::{Alias, AliasStore, NodeId};
use radicle::prelude::Did;
@@ -31,7 +31,16 @@ pub fn oid(oid: impl Into<radicle::git::Oid>) -> Paint<String> {
Paint::new(format!(
"{:.abbrev$}",
oid.into(),
- abbrev = git::get_abbrev()
+ abbrev = git::get_abbrev_cwd()
+ ))
+}
+
+/// Format a git Oid based on its belonging RID.
+pub fn oid_rid(oid: impl Into<radicle::git::Oid>, rid: &RepoId) -> Paint<String> {
+ Paint::new(format!(
+ "{:.abbrev$}",
+ oid.into(),
+ abbrev = git::get_abbrev_rid(rid)
))
}
@@ -55,7 +64,16 @@ pub fn cob(id: &ObjectId) -> Paint<String> {
Paint::new(format!(
"{:.abbrev$}",
id.to_string(),
- abbrev = git::get_abbrev()
+ abbrev = git::get_abbrev_cwd()
+ ))
+}
+
+/// Format a COB id based on its belonging RID.
+pub fn cob_rid(id: &ObjectId, rid: &RepoId) -> Paint<String> {
+ Paint::new(format!(
+ "{:.abbrev$}",
+ id.to_string(),
+ abbrev = git::get_abbrev_rid(rid)
))
}
Exit code: 0
shell: 'cargo --version rustc --version cargo fmt --check cargo clippy --all-targets --workspace -- --deny clippy::all cargo build --all-targets --workspace cargo doc --workspace cargo test --workspace --no-fail-fast '
Commands:
$ podman run --name d42540e2-c725-48bb-8e7c-b4d327ea055f -v /opt/radcis/ci.rad.levitte.org/cci/state/d42540e2-c725-48bb-8e7c-b4d327ea055f/s:/d42540e2-c725-48bb-8e7c-b4d327ea055f/s:ro -v /opt/radcis/ci.rad.levitte.org/cci/state/d42540e2-c725-48bb-8e7c-b4d327ea055f/w:/d42540e2-c725-48bb-8e7c-b4d327ea055f/w -w /d42540e2-c725-48bb-8e7c-b4d327ea055f/w -v /opt/radcis/ci.rad.levitte.org/.radicle:/${id}/.radicle:ro -e RAD_HOME=/${id}/.radicle rust:bookworm bash /d42540e2-c725-48bb-8e7c-b4d327ea055f/s/script.sh
+ cargo --version
info: syncing channel updates for '1.77-x86_64-unknown-linux-gnu'
info: latest update on 2024-04-09, rust version 1.77.2 (25ef9e3d8 2024-04-09)
info: downloading component 'cargo'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: installing component 'cargo'
info: installing component 'rust-std'
info: installing component 'rustc'
cargo 1.77.2 (e52e36006 2024-03-26)
+ rustc --version
rustc 1.77.2 (25ef9e3d8 2024-04-09)
+ cargo fmt --check
error: 'cargo-fmt' is not installed for the toolchain '1.77-x86_64-unknown-linux-gnu'.
To install, run `rustup component add --toolchain 1.77-x86_64-unknown-linux-gnu rustfmt`
Exit code: 1
{
"response": "finished",
"result": "failure"
}