67 lines · 1.7 KB · Rust
RawDownload
use anyhow::{Context, Result};use git_repository as git; pub fn describe(    repo: git::Repository,    rev_spec: Option<&str>,    mut out: impl std::io::Write,    mut err: impl std::io::Write,    describe::Options {        all_tags,        all_refs,        first_parent,        always,        statistics,        max_candidates,        long_format,    }: describe::Options,) -> Result<()> {    let commit = match rev_spec {        Some(spec) => repo            .rev_parse(spec)?            .single()            .context("Need single revision revspec")?            .object()?            .try_into_commit()?,        None => repo.head_commit()?,    };    use git::commit::describe::SelectRef::*;    let select_ref = if all_refs {        AllRefs    } else if all_tags {        AllTags    } else {        Default::default()    };    let resolution = commit        .describe()        .names(select_ref)        .traverse_first_parent(first_parent)        .id_as_fallback(always)        .max_candidates(max_candidates)        .try_resolve()?        .with_context(|| format!("Did not find a single candidate ref for naming id '{}'", commit.id))?;     if statistics {        writeln!(err, "traversed {} commits", resolution.outcome.commits_seen)?;    }     let mut describe_id = resolution.format()?;    describe_id.long(long_format);     writeln!(out, "{}", describe_id)?;    Ok(())} pub mod describe {    #[derive(Debug, Clone)]    pub struct Options {        pub all_tags: bool,        pub all_refs: bool,        pub first_parent: bool,        pub always: bool,        pub long_format: bool,        pub statistics: bool,        pub max_candidates: usize,    }}