History

feat: support for `commitgraph list from..to` to exercise the new 'hide' capability.

Sebastian Thiel committed 1 year ago

Commit c5bc49f1 parent a9befb24 files · +70 −26Browse files

Showing the changes to gitoxide-core/src/repository/commitgraph (1 of 4 files). Show all

Unified · Split

gitoxide-core/src/repository/commitgraph/list.rs+61−24
@@ -1,55 +1,92 @@
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 {
1618 bail!("Only human output is currently supported");
1719 }
1820 let graph = repo
19− .commit_graph()
21+ .commit_graph_if_enabled()
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(),
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+ ))
4959 ))
50− )
5160 )?;
5261 }
5362 Ok(())
5463 }
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+ }
5592 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t