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 @@
1pub(crate) mod function {1pub(crate) mod function {
2 use std::{borrow::Cow, ffi::OsString};2 use crate::OutputFormat;
3
4 use anyhow::{bail, Context};3 use anyhow::{bail, Context};
4 use gix::odb::store::RefreshMode;
5 use gix::revision::plumbing::Spec;
5 use gix::{prelude::ObjectIdExt, revision::walk::Sorting};6 use gix::{prelude::ObjectIdExt, revision::walk::Sorting};
6 7 use std::fmt::Formatter;
7 use crate::OutputFormat;8 use std::{borrow::Cow, ffi::OsString};
8 9
9 pub fn list(10 pub fn list(
10 mut repo: gix::Repository,11 mut repo: gix::Repository,
11 spec: OsString,12 spec: OsString,
12 mut out: impl std::io::Write,13 mut out: impl std::io::Write,
14 long_hashes: bool,
13 format: OutputFormat,15 format: OutputFormat,
14 ) -> anyhow::Result<()> {16 ) -> anyhow::Result<()> {
15 if format != OutputFormat::Human {17 if format != OutputFormat::Human {
16 bail!("Only human output is currently supported");18 bail!("Only human output is currently supported");
17 }19 }
18 let graph = repo20 let graph = repo
19 .commit_graph()21 .commit_graph_if_enabled()
20 .context("a commitgraph is required, but none was found")?;22 .context("a commitgraph is required, but none was found")?;
21 repo.object_cache_size_if_unset(4 * 1024 * 1024);23 repo.object_cache_size_if_unset(4 * 1024 * 1024);
24 repo.objects.refresh = RefreshMode::Never;
22 25
23 let spec = gix::path::os_str_into_bstr(&spec)?;26 let spec = gix::path::os_str_into_bstr(&spec)?;
24 let id = repo27 let spec = repo.rev_parse(spec)?.detach();
25 .rev_parse_single(spec)28 let commits = match spec {
26 .context("Only single revisions are currently supported")?;29 Spec::Include(id) => connected_commit_id(&repo, id)?
27 let commits = id30 .ancestors()
28 .object()?31 .sorting(Sorting::ByCommitTime(Default::default()))
29 .peel_to_kind(gix::object::Kind::Commit)32 .all()?,
30 .context("Need committish as starting point")?33 Spec::Range { from, to } => connected_commit_id(&repo, to)?
31 .id()34 .ancestors()
32 .ancestors()35 .sorting(Sorting::ByCommitTime(Default::default()))
33 .sorting(Sorting::ByCommitTime(Default::default()))36 .with_hidden(Some(connected_commit_id(&repo, from)?))
34 .all()?;37 .all()?,
38 Spec::Exclude(_) | Spec::Merge { .. } | Spec::IncludeOnlyParents(_) | Spec::ExcludeParents(_) => {
39 bail!("The spec isn't currently supported: {spec:?}")
40 }
41 };
35 for commit in commits {42 for commit in commits {
36 let commit = commit?;43 let commit = commit?;
37 writeln!(44 writeln!(
38 out,45 out,
39 "{} {} {} {}",46 "{} {} {} {}",
40 commit.id().shorten_or_id(),47 HexId::new(commit.id(), long_hashes),
41 commit.commit_time.expect("traversal with date"),48 commit.commit_time.expect("traversal with date"),
42 commit.parent_ids.len(),49 commit.parent_ids.len(),
43 graph.commit_by_id(commit.id).map_or_else(50 graph
44 || Cow::Borrowed("<NOT IN GRAPH-CACHE>"),51 .as_ref()
45 |c| Cow::Owned(format!(52 .map_or(Cow::Borrowed(""), |graph| graph.commit_by_id(commit.id).map_or_else(
46 "{} {}",53 || Cow::Borrowed("<NOT IN GRAPH-CACHE>"),
47 c.root_tree_id().to_owned().attach(&repo).shorten_or_id(),54 |c| Cow::Owned(format!(
48 c.generation()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 Ok(())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}

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