Skip to content

Commit

Permalink
Merge branch 'future-dates'
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Jun 11, 2023
2 parents 2560a2c + 101dec0 commit 8d2e6a9
Show file tree
Hide file tree
Showing 82 changed files with 740 additions and 420 deletions.
10 changes: 10 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion cargo-smart-release/src/commit/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ pub struct Segment<'a> {
pub struct Item {
pub id: gix::ObjectId,
pub message: Message,
pub commit_time: gix::actor::Time,
pub commit_time: gix::date::Time,
pub tree_id: gix::ObjectId,
pub parent_tree_id: Option<gix::ObjectId>,
}
Expand Down
6 changes: 3 additions & 3 deletions cargo-smart-release/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ mod tests {
}
}

pub fn time_to_offset_date_time(time: gix::actor::Time) -> OffsetDateTime {
time::OffsetDateTime::from_unix_timestamp(time.seconds_since_unix_epoch as i64)
pub fn time_to_offset_date_time(time: gix::date::Time) -> OffsetDateTime {
time::OffsetDateTime::from_unix_timestamp(time.seconds as i64)
.expect("always valid unix time")
.replace_offset(time::UtcOffset::from_whole_seconds(time.offset_in_seconds).expect("valid offset"))
.replace_offset(time::UtcOffset::from_whole_seconds(time.offset).expect("valid offset"))
}
57 changes: 57 additions & 0 deletions gitoxide-core/src/commitgraph/list.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
pub(crate) mod function {
use std::borrow::Cow;
use std::ffi::OsString;

use anyhow::{bail, Context};
use gix::prelude::ObjectIdExt;
use gix::traverse::commit::Sorting;

use crate::OutputFormat;

pub fn list(
mut repo: gix::Repository,
spec: OsString,
mut out: impl std::io::Write,
format: OutputFormat,
) -> anyhow::Result<()> {
if format != OutputFormat::Human {
bail!("Only human output is currently supported");
}
let graph = repo
.commit_graph()
.context("a commitgraph is required, but none was found")?;
repo.object_cache_size_if_unset(4 * 1024 * 1024);

let spec = gix::path::os_str_into_bstr(&spec)?;
let id = repo
.rev_parse_single(spec)
.context("Only single revisions are currently supported")?;
let commits = id
.object()?
.peel_to_kind(gix::object::Kind::Commit)
.context("Need commitish as starting point")?
.id()
.ancestors()
.sorting(Sorting::ByCommitTimeNewestFirst)
.all()?;
for commit in commits {
let commit = commit?;
writeln!(
out,
"{} {} {} {}",
commit.id().shorten_or_id(),
commit.commit_time.expect("traversal with date"),
commit.parent_ids.len(),
graph.commit_by_id(commit.id).map_or_else(
|| Cow::Borrowed("<NOT IN GRAPH-CACHE>"),
|c| Cow::Owned(format!(
"{} {}",
c.root_tree_id().to_owned().attach(&repo).shorten_or_id(),
c.generation()
))
)
)?;
}
Ok(())
}
}
4 changes: 4 additions & 0 deletions gitoxide-core/src/commitgraph/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,5 @@
pub mod list;
pub use list::function::list;

pub mod verify;
pub use verify::function::verify;
107 changes: 50 additions & 57 deletions gitoxide-core/src/commitgraph/verify.rs
Original file line number Diff line number Diff line change
@@ -1,77 +1,70 @@
use std::{io, path::Path};

use anyhow::{Context as AnyhowContext, Result};
use gix::commitgraph::Graph;

use crate::OutputFormat;

/// A general purpose context for many operations provided here
pub struct Context<W1: io::Write, W2: io::Write> {
pub struct Context<W1: std::io::Write, W2: std::io::Write> {
/// A stream to which to output errors
pub err: W2,
/// A stream to which to output operation results
pub out: W1,
pub output_statistics: Option<OutputFormat>,
}

impl Default for Context<Vec<u8>, Vec<u8>> {
fn default() -> Self {
pub(crate) mod function {
use std::io;

use crate::commitgraph::verify::Context;
use crate::OutputFormat;
use anyhow::{Context as AnyhowContext, Result};

pub fn verify<W1, W2>(
repo: gix::Repository,
Context {
err: Vec::new(),
out: Vec::new(),
output_statistics: None,
}
}
}
err: _err,
mut out,
output_statistics,
}: Context<W1, W2>,
) -> Result<gix::commitgraph::verify::Outcome>
where
W1: io::Write,
W2: io::Write,
{
let g = repo.commit_graph()?;

pub fn graph_or_file<W1, W2>(
path: impl AsRef<Path>,
Context {
err: _err,
mut out,
output_statistics,
}: Context<W1, W2>,
) -> Result<gix::commitgraph::verify::Outcome>
where
W1: io::Write,
W2: io::Write,
{
let g = Graph::at(path).with_context(|| "Could not open commit graph")?;
#[allow(clippy::unnecessary_wraps, unknown_lints)]
fn noop_processor(_commit: &gix::commitgraph::file::Commit<'_>) -> std::result::Result<(), std::fmt::Error> {
Ok(())
}
let stats = g
.verify_integrity(noop_processor)
.with_context(|| "Verification failure")?;

#[allow(clippy::unnecessary_wraps, unknown_lints)]
fn noop_processor(_commit: &gix::commitgraph::file::Commit<'_>) -> std::result::Result<(), std::fmt::Error> {
Ok(())
}
let stats = g
.verify_integrity(noop_processor)
.with_context(|| "Verification failure")?;
#[cfg_attr(not(feature = "serde"), allow(clippy::single_match))]
match output_statistics {
Some(OutputFormat::Human) => drop(print_human_output(&mut out, &stats)),
#[cfg(feature = "serde")]
Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, &stats)?,
_ => {}
}

#[cfg_attr(not(feature = "serde"), allow(clippy::single_match))]
match output_statistics {
Some(OutputFormat::Human) => drop(print_human_output(&mut out, &stats)),
#[cfg(feature = "serde")]
Some(OutputFormat::Json) => serde_json::to_writer_pretty(out, &stats)?,
_ => {}
Ok(stats)
}

Ok(stats)
}
fn print_human_output(out: &mut impl io::Write, stats: &gix::commitgraph::verify::Outcome) -> io::Result<()> {
writeln!(out, "number of commits with the given number of parents")?;
let mut parent_counts: Vec<_> = stats.parent_counts.iter().map(|(a, b)| (*a, *b)).collect();
parent_counts.sort_by_key(|e| e.0);
for (parent_count, commit_count) in parent_counts.into_iter() {
writeln!(out, "\t{parent_count:>2}: {commit_count}")?;
}
writeln!(out, "\t->: {}", stats.num_commits)?;

fn print_human_output(out: &mut impl io::Write, stats: &gix::commitgraph::verify::Outcome) -> io::Result<()> {
writeln!(out, "number of commits with the given number of parents")?;
let mut parent_counts: Vec<_> = stats.parent_counts.iter().map(|(a, b)| (*a, *b)).collect();
parent_counts.sort_by_key(|e| e.0);
for (parent_count, commit_count) in parent_counts.into_iter() {
writeln!(out, "\t{parent_count:>2}: {commit_count}")?;
}
writeln!(out, "\t->: {}", stats.num_commits)?;
write!(out, "\nlongest path length between two commits: ")?;
if let Some(n) = stats.longest_path_length {
writeln!(out, "{n}")?;
} else {
writeln!(out, "unknown")?;
}

write!(out, "\nlongest path length between two commits: ")?;
if let Some(n) = stats.longest_path_length {
writeln!(out, "{n}")?;
} else {
writeln!(out, "unknown")?;
Ok(())
}

Ok(())
}
6 changes: 1 addition & 5 deletions gitoxide-core/src/hours/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ pub fn estimate_hours(
let hours_for_commits = commits.iter().map(|t| &t.1).rev().tuple_windows().fold(
0_f32,
|hours, (cur, next): (&gix::actor::SignatureRef<'_>, &gix::actor::SignatureRef<'_>)| {
let change_in_minutes = (next
.time
.seconds_since_unix_epoch
.saturating_sub(cur.time.seconds_since_unix_epoch)) as f32
/ MINUTES_PER_HOUR;
let change_in_minutes = (next.time.seconds.saturating_sub(cur.time.seconds)) as f32 / MINUTES_PER_HOUR;
if change_in_minutes < MAX_COMMIT_DIFFERENCE_IN_MINUTES {
hours + change_in_minutes / MINUTES_PER_HOUR
} else {
Expand Down
9 changes: 3 additions & 6 deletions gitoxide-core/src/hours/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,9 @@ where
}
out.shrink_to_fit();
out.sort_by(|a, b| {
a.1.email.cmp(b.1.email).then(
a.1.time
.seconds_since_unix_epoch
.cmp(&b.1.time.seconds_since_unix_epoch)
.reverse(),
)
a.1.email
.cmp(b.1.email)
.then(a.1.time.seconds.cmp(&b.1.time.seconds).reverse())
});
Ok(out)
});
Expand Down
21 changes: 15 additions & 6 deletions gitoxide-core/src/repository/revision/list.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::ffi::OsString;

use anyhow::{bail, Context};
use gix::prelude::ObjectIdExt;
use gix::traverse::commit::Sorting;

use crate::OutputFormat;

Expand All @@ -20,14 +20,23 @@ pub fn list(
let id = repo
.rev_parse_single(spec)
.context("Only single revisions are currently supported")?;
let commit_id = id
let commits = id
.object()?
.peel_to_kind(gix::object::Kind::Commit)
.context("Need commitish as starting point")?
.id
.attach(&repo);
for commit in commit_id.ancestors().all()? {
writeln!(out, "{}", commit?.id().to_hex())?;
.id()
.ancestors()
.sorting(Sorting::ByCommitTimeNewestFirst)
.all()?;
for commit in commits {
let commit = commit?;
writeln!(
out,
"{} {} {}",
commit.id().shorten_or_id(),
commit.commit_time.expect("traversal with date"),
commit.parent_ids.len()
)?;
}
Ok(())
}
10 changes: 9 additions & 1 deletion gix-actor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,16 @@
#![deny(missing_docs, rust_2018_idioms)]
#![forbid(unsafe_code)]

/// The re-exported `bstr` crate.
///
/// For convenience to allow using `bstr` without adding it to own cargo manifest.
pub use bstr;
use bstr::{BStr, BString};
pub use gix_date::{time::Sign, Time};
/// The re-exported `gix-date` crate.
///
/// For convenience to allow using `gix-date` without adding it to own cargo manifest.
pub use gix_date as date;
use gix_date::Time;

mod identity;
///
Expand Down
Loading

0 comments on commit 8d2e6a9

Please sign in to comment.