|
1 | 1 | pub(crate) mod function { |
2 | | - use std::{borrow::Cow, ffi::OsString}; |
3 | | - |
| 2 | + use crate::OutputFormat; |
4 | 3 | use anyhow::{bail, Context}; |
| 4 | + use gix::odb::store::RefreshMode; |
| 5 | + use gix::revision::plumbing::Spec; |
5 | 6 | use gix::{prelude::ObjectIdExt, revision::walk::Sorting}; |
6 | | - |
7 | | - use crate::OutputFormat; |
| 7 | + use std::fmt::Formatter; |
| 8 | + use std::{borrow::Cow, ffi::OsString}; |
8 | 9 |
|
9 | 10 | pub fn list( |
10 | 11 | mut repo: gix::Repository, |
11 | 12 | spec: OsString, |
12 | 13 | mut out: impl std::io::Write, |
| 14 | + long_hashes: bool, |
13 | 15 | format: OutputFormat, |
14 | 16 | ) -> anyhow::Result<()> { |
15 | 17 | if format != OutputFormat::Human { |
16 | 18 | bail!("Only human output is currently supported"); |
17 | 19 | } |
18 | 20 | let graph = repo |
19 | | - .commit_graph() |
| 21 | + .commit_graph_if_enabled() |
20 | 22 | .context("a commitgraph is required, but none was found")?; |
21 | 23 | repo.object_cache_size_if_unset(4 * 1024 * 1024); |
| 24 | + repo.objects.refresh = RefreshMode::Never; |
22 | 25 |
|
23 | 26 | let spec = gix::path::os_str_into_bstr(&spec)?; |
24 | | - let id = repo |
25 | | - .rev_parse_single(spec) |
26 | | - .context("Only single revisions are currently supported")?; |
27 | | - let commits = id |
28 | | - .object()? |
29 | | - .peel_to_kind(gix::object::Kind::Commit) |
30 | | - .context("Need committish as starting point")? |
31 | | - .id() |
32 | | - .ancestors() |
33 | | - .sorting(Sorting::ByCommitTime(Default::default())) |
34 | | - .all()?; |
| 27 | + let spec = repo.rev_parse(spec)?.detach(); |
| 28 | + let commits = match spec { |
| 29 | + Spec::Include(id) => connected_commit_id(&repo, id)? |
| 30 | + .ancestors() |
| 31 | + .sorting(Sorting::ByCommitTime(Default::default())) |
| 32 | + .all()?, |
| 33 | + Spec::Range { from, to } => connected_commit_id(&repo, to)? |
| 34 | + .ancestors() |
| 35 | + .sorting(Sorting::ByCommitTime(Default::default())) |
| 36 | + .with_hidden(Some(connected_commit_id(&repo, from)?)) |
| 37 | + .all()?, |
| 38 | + Spec::Exclude(_) | Spec::Merge { .. } | Spec::IncludeOnlyParents(_) | Spec::ExcludeParents(_) => { |
| 39 | + bail!("The spec isn't currently supported: {spec:?}") |
| 40 | + } |
| 41 | + }; |
35 | 42 | for commit in commits { |
36 | 43 | let commit = commit?; |
37 | 44 | writeln!( |
38 | 45 | out, |
39 | 46 | "{} {} {} {}", |
40 | | - commit.id().shorten_or_id(), |
| 47 | + HexId::new(commit.id(), long_hashes), |
41 | 48 | commit.commit_time.expect("traversal with date"), |
42 | 49 | commit.parent_ids.len(), |
43 | | - graph.commit_by_id(commit.id).map_or_else( |
44 | | - || Cow::Borrowed("<NOT IN GRAPH-CACHE>"), |
45 | | - |c| Cow::Owned(format!( |
46 | | - "{} {}", |
47 | | - c.root_tree_id().to_owned().attach(&repo).shorten_or_id(), |
48 | | - c.generation() |
| 50 | + graph |
| 51 | + .as_ref() |
| 52 | + .map_or(Cow::Borrowed(""), |graph| graph.commit_by_id(commit.id).map_or_else( |
| 53 | + || Cow::Borrowed("<NOT IN GRAPH-CACHE>"), |
| 54 | + |c| Cow::Owned(format!( |
| 55 | + "{} {}", |
| 56 | + HexId::new(c.root_tree_id().to_owned().attach(&repo), long_hashes), |
| 57 | + c.generation() |
| 58 | + )) |
49 | 59 | )) |
50 | | - ) |
51 | 60 | )?; |
52 | 61 | } |
53 | 62 | Ok(()) |
54 | 63 | } |
| 64 | + |
| 65 | + fn connected_commit_id(repo: &gix::Repository, id: gix::ObjectId) -> anyhow::Result<gix::Id<'_>> { |
| 66 | + Ok(id |
| 67 | + .attach(repo) |
| 68 | + .object()? |
| 69 | + .peel_to_kind(gix::object::Kind::Commit) |
| 70 | + .context("Need committish as starting point")? |
| 71 | + .id()) |
| 72 | + } |
| 73 | + |
| 74 | + struct HexId<'a>(gix::Id<'a>, bool); |
| 75 | + |
| 76 | + impl<'a> HexId<'a> { |
| 77 | + pub fn new(id: gix::Id<'a>, long_hex: bool) -> Self { |
| 78 | + HexId(id, long_hex) |
| 79 | + } |
| 80 | + } |
| 81 | + |
| 82 | + impl std::fmt::Display for HexId<'_> { |
| 83 | + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { |
| 84 | + let HexId(id, long_hex) = self; |
| 85 | + if *long_hex { |
| 86 | + id.fmt(f) |
| 87 | + } else { |
| 88 | + id.shorten_or_id().fmt(f) |
| 89 | + } |
| 90 | + } |
| 91 | + } |
55 | 92 | } |
0 commit comments