Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: use git config's `core.abbrev` for SHA-1 abbrevs
◌ CI pending RadsammyT committed 2 years ago
commit f7c0ffc31c64af0236d460997a76add537d061d5
parent bb5355fcb1a47e6a6ac3e441e2b807906d7ef135
1 pending (1 total) View logs
2 files changed +70 -5
modified radicle-cli/src/git.rs
@@ -35,6 +35,9 @@ pub const CONFIG_SIGNING_KEY: &str = "user.signingkey";
pub const CONFIG_GPG_FORMAT: &str = "gpg.format";
pub const CONFIG_GPG_SSH_PROGRAM: &str = "gpg.ssh.program";
pub const CONFIG_GPG_SSH_ALLOWED_SIGNERS: &str = "gpg.ssh.allowedSignersFile";
+
pub const CONFIG_ABBREV_DEFAULT: usize = 10;
+

+
static mut CONFIG_ABBREV: Option<usize> = None;

/// Git revision parameter. Supports extended SHA-1 syntax.
#[derive(Debug, Clone, PartialEq, Eq)]
@@ -331,6 +334,59 @@ pub fn check_version() -> Result<Version, anyhow::Error> {
    Ok(git_version)
}

+
/// Gets git's global `core.abbrev` config for formatting.
+
/// Returns `CONFIG_ABBREV_DEFAULT` otherwise.
+
/// This function contains unsafe code as this reads
+
/// (and writes if called for the first time) from a mutable static.
+
pub fn get_abbrev() -> usize {
+
    // UNSAFE: as we need to read from a mutable static.
+
    unsafe {
+
        match CONFIG_ABBREV {
+
            None => {
+
                let abbrev = if let Ok(cfg) = git2::Config::open_default() {
+
                    if let Ok(entry) = cfg.get_entry("core.abbrev") {
+
                        entry
+
                            .value()
+
                            .unwrap_or("auto")
+
                            .to_string()
+
                    } else {
+
                        String::from("auto")
+
                    }
+
                } else {
+
                    String::from("auto")
+
                };
+
                match abbrev.trim() {
+
                    "auto" => {
+
                        // Here, since there isn't an orthodox way to get auto's
+
                        // true value (yet), we instead get git to do it for us.
+
                        // The length of the revision is what we are looking for.
+
                        CONFIG_ABBREV = Some(
+
                            git(Path::new("."), ["rev-parse", "--short", "HEAD"])
+
                                .unwrap_or("a".repeat(CONFIG_ABBREV_DEFAULT))
+
                                .trim()
+
                                .len(),
+
                        );
+
                    }
+
                    "no" => CONFIG_ABBREV = Some(40),
+
                    _ => {
+
                        CONFIG_ABBREV = Some(
+
                            abbrev
+
                                .parse::<usize>()
+
                                .unwrap_or(CONFIG_ABBREV_DEFAULT)
+
                                .clamp(4, 40),
+
                        );
+
                    }
+
                }
+

+
                //SAFETY: We have already set CONFIG_ABBREV to a Some value. This should never
+
                //change again.
+
                CONFIG_ABBREV.unwrap()
+
            }
+
            Some(x) => x,
+
        }
+
    }
+
}
+

/// Parse a remote refspec into a peer id and ref.
pub fn parse_remote(refspec: &str) -> Option<(NodeId, &str)> {
    refspec
@@ -348,9 +404,9 @@ pub fn view_diff(
    let workdir = repo
        .workdir()
        .ok_or_else(|| anyhow!("Could not get workdir current repository."))?;
-

-
    let left = format!("{:.7}", left.to_string());
-
    let right = format!("{:.7}", right.to_string());
+
    let abbrev = get_abbrev();
+
    let left = format!("{:.abbrev$}", left.to_string());
+
    let right = format!("{:.abbrev$}", right.to_string());

    let mut git = Command::new("git")
        .current_dir(workdir)
modified radicle-cli/src/terminal/format.rs
@@ -14,6 +14,7 @@ use radicle::profile::{env, Profile};
use radicle::storage::RefUpdate;
use radicle_term::element::Line;

+
use crate::git;
use crate::terminal as term;

/// Format a node id to be more compact.
@@ -27,7 +28,11 @@ pub fn node(node: &NodeId) -> Paint<String> {

/// Format a git Oid.
pub fn oid(oid: impl Into<radicle::git::Oid>) -> Paint<String> {
-
    Paint::new(format!("{:.7}", oid.into()))
+
    Paint::new(format!(
+
        "{:.abbrev$}",
+
        oid.into(),
+
        abbrev = git::get_abbrev()
+
    ))
}

/// Wrap parenthesis around styled input, eg. `"input"` -> `"(input)"`.
@@ -47,7 +52,11 @@ pub fn command<D: fmt::Display>(cmd: D) -> Paint<String> {

/// Format a COB id.
pub fn cob(id: &ObjectId) -> Paint<String> {
-
    Paint::new(format!("{:.7}", id.to_string()))
+
    Paint::new(format!(
+
        "{:.abbrev$}",
+
        id.to_string(),
+
        abbrev = git::get_abbrev()
+
    ))
}

/// Format a DID.