Skip to content

Commit 16913bc

Browse files
committed
feat: support for commitgraph list from..to to exercise the new 'hide' capability.
1 parent be835b6 commit 16913bc

File tree

3 files changed

+57
-19
lines changed

3 files changed

+57
-19
lines changed
Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
pub(crate) mod function {
2-
use std::{borrow::Cow, ffi::OsString};
3-
2+
use crate::OutputFormat;
43
use anyhow::{bail, Context};
4+
use gix::odb::store::RefreshMode;
5+
use gix::revision::plumbing::Spec;
56
use gix::{prelude::ObjectIdExt, revision::walk::Sorting};
6-
7-
use crate::OutputFormat;
7+
use std::fmt::Formatter;
8+
use std::{borrow::Cow, ffi::OsString};
89

910
pub fn list(
1011
mut repo: gix::Repository,
1112
spec: OsString,
1213
mut out: impl std::io::Write,
14+
long_hashes: bool,
1315
format: OutputFormat,
1416
) -> anyhow::Result<()> {
1517
if format != OutputFormat::Human {
@@ -19,37 +21,70 @@ pub(crate) mod function {
1921
.commit_graph()
2022
.context("a commitgraph is required, but none was found")?;
2123
repo.object_cache_size_if_unset(4 * 1024 * 1024);
24+
repo.objects.refresh = RefreshMode::Never;
2225

2326
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+
};
3542
for commit in commits {
3643
let commit = commit?;
3744
writeln!(
3845
out,
3946
"{} {} {} {}",
40-
commit.id().shorten_or_id(),
47+
HexId::new(commit.id(), long_hashes),
4148
commit.commit_time.expect("traversal with date"),
4249
commit.parent_ids.len(),
4350
graph.commit_by_id(commit.id).map_or_else(
4451
|| Cow::Borrowed("<NOT IN GRAPH-CACHE>"),
4552
|c| Cow::Owned(format!(
4653
"{} {}",
47-
c.root_tree_id().to_owned().attach(&repo).shorten_or_id(),
54+
HexId::new(c.root_tree_id().to_owned().attach(&repo), long_hashes),
4855
c.generation()
4956
))
5057
)
5158
)?;
5259
}
5360
Ok(())
5461
}
62+
63+
fn connected_commit_id(repo: &gix::Repository, id: gix::ObjectId) -> anyhow::Result<gix::Id<'_>> {
64+
Ok(id
65+
.attach(&repo)
66+
.object()?
67+
.peel_to_kind(gix::object::Kind::Commit)
68+
.context("Need committish as starting point")?
69+
.id())
70+
}
71+
72+
struct HexId<'a>(gix::Id<'a>, bool);
73+
74+
impl<'a> HexId<'a> {
75+
pub fn new(id: gix::Id<'a>, long_hex: bool) -> Self {
76+
HexId(id, long_hex)
77+
}
78+
}
79+
80+
impl<'a> std::fmt::Display for HexId<'a> {
81+
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
82+
let HexId(id, long_hex) = self;
83+
if *long_hex {
84+
id.fmt(f)
85+
} else {
86+
id.shorten_or_id().fmt(f)
87+
}
88+
}
89+
}
5590
}

src/plumbing/main.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,15 +543,15 @@ pub fn main() -> Result<()> {
543543
)
544544
}
545545
Subcommands::CommitGraph(cmd) => match cmd {
546-
commitgraph::Subcommands::List { spec } => prepare_and_run(
546+
commitgraph::Subcommands::List { long_hashes, spec } => prepare_and_run(
547547
"commitgraph-list",
548548
trace,
549549
auto_verbose,
550550
progress,
551551
progress_keep_open,
552552
None,
553553
move |_progress, out, _err| {
554-
core::repository::commitgraph::list(repository(Mode::Lenient)?, spec, out, format)
554+
core::repository::commitgraph::list(repository(Mode::Lenient)?, spec, out, long_hashes, format)
555555
},
556556
)
557557
.map(|_| ()),

src/plumbing/options/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,9 @@ pub mod commitgraph {
955955
},
956956
/// List all entries in the commit-graph file as reachable by starting from `HEAD`.
957957
List {
958+
/// Display long hashes, instead of expensively shortened versions for best performance.
959+
#[clap(long, short = 'l')]
960+
long_hashes: bool,
958961
/// The rev-spec to list reachable commits from.
959962
#[clap(default_value = "@")]
960963
spec: std::ffi::OsString,

0 commit comments

Comments
 (0)