|
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