1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
pub(crate) mod function {
    use std::{borrow::Cow, ffi::OsString};

    use anyhow::{bail, Context};
    use gix::{prelude::ObjectIdExt, traverse::commit::simple::Sorting};

    use crate::OutputFormat;

    pub fn list(
        mut repo: gix::Repository,
        spec: OsString,
        mut out: impl std::io::Write,
        format: OutputFormat,
    ) -> anyhow::Result<()> {
        if format != OutputFormat::Human {
            bail!("Only human output is currently supported");
        }
        let graph = repo
            .commit_graph()
            .context("a commitgraph is required, but none was found")?;
        repo.object_cache_size_if_unset(4 * 1024 * 1024);

        let spec = gix::path::os_str_into_bstr(&spec)?;
        let id = repo
            .rev_parse_single(spec)
            .context("Only single revisions are currently supported")?;
        let commits = id
            .object()?
            .peel_to_kind(gix::object::Kind::Commit)
            .context("Need committish as starting point")?
            .id()
            .ancestors()
            .sorting(Sorting::ByCommitTimeNewestFirst)
            .all()?;
        for commit in commits {
            let commit = commit?;
            writeln!(
                out,
                "{} {} {} {}",
                commit.id().shorten_or_id(),
                commit.commit_time.expect("traversal with date"),
                commit.parent_ids.len(),
                graph.commit_by_id(commit.id).map_or_else(
                    || Cow::Borrowed("<NOT IN GRAPH-CACHE>"),
                    |c| Cow::Owned(format!(
                        "{} {}",
                        c.root_tree_id().to_owned().attach(&repo).shorten_or_id(),
                        c.generation()
                    ))
                )
            )?;
        }
        Ok(())
    }
}