From 791dd666430fe0586c7db75b352487a72d3789e7 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Wed, 31 Aug 2022 10:07:59 +0800 Subject: [PATCH] A basic implementation of rev-list without anything fancy --- README.md | 1 + gitoxide-core/src/repository/revision/list.rs | 27 +++++++++++++++++++ gitoxide-core/src/repository/revision/mod.rs | 4 ++- .../repository/revision/previous_branches.rs | 6 ++++- src/plumbing/main.rs | 10 +++++++ src/plumbing/options.rs | 3 +++ 6 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 gitoxide-core/src/repository/revision/list.rs diff --git a/README.md b/README.md index 9f740c4eaf1..4df931cd798 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ Please see _'Development Status'_ for a listing of all crates and their capabili * **mailmap** * [x] **entries** - display all entries of the aggregated mailmap git would use for substitution * **revision** + * [x] **list** - list plain revision hashes from a starting point, similar to a very simple version of `git rev-list`. * [x] **explain** - show what would be done while parsing a revision specification like `HEAD~1` * [x] **resolve** - show which objects a revspec resolves to, similar to `git rev-parse` but faster and with much better error handling * [x] **previous-branches** - list all previously checked out branches, powered by the ref-log. diff --git a/gitoxide-core/src/repository/revision/list.rs b/gitoxide-core/src/repository/revision/list.rs new file mode 100644 index 00000000000..f3f34f90cd9 --- /dev/null +++ b/gitoxide-core/src/repository/revision/list.rs @@ -0,0 +1,27 @@ +use anyhow::{bail, Context}; +use git_repository as git; +use std::ffi::OsString; + +use crate::OutputFormat; + +pub fn list( + mut repo: git::Repository, + spec: OsString, + mut out: impl std::io::Write, + format: OutputFormat, +) -> anyhow::Result<()> { + if format != OutputFormat::Human { + bail!("Only human output is currently supported"); + } + repo.object_cache_size_if_unset(4 * 1024 * 1024); + + let spec = git::path::os_str_into_bstr(&spec)?; + let id = repo + .rev_parse(spec)? + .single() + .context("Only single revisions are currently supported")?; + for commit in id.ancestors().all()? { + writeln!(out, "{}", commit?.to_hex())?; + } + Ok(()) +} diff --git a/gitoxide-core/src/repository/revision/mod.rs b/gitoxide-core/src/repository/revision/mod.rs index 3e8937e29f2..5e5dda98af5 100644 --- a/gitoxide-core/src/repository/revision/mod.rs +++ b/gitoxide-core/src/repository/revision/mod.rs @@ -1,3 +1,5 @@ +mod list; +pub use list::list; mod explain; pub use explain::explain; @@ -5,4 +7,4 @@ pub mod resolve; pub use resolve::function::resolve; mod previous_branches; -pub use previous_branches::function as previous_branches; +pub use previous_branches::previous_branches; diff --git a/gitoxide-core/src/repository/revision/previous_branches.rs b/gitoxide-core/src/repository/revision/previous_branches.rs index 1cd39aa6e85..b22e6398eee 100644 --- a/gitoxide-core/src/repository/revision/previous_branches.rs +++ b/gitoxide-core/src/repository/revision/previous_branches.rs @@ -3,7 +3,11 @@ use git_repository as git; use crate::OutputFormat; -pub fn function(repo: git::Repository, mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> { +pub fn previous_branches( + repo: git::Repository, + mut out: impl std::io::Write, + format: OutputFormat, +) -> anyhow::Result<()> { let branches = repo .head()? .prior_checked_out_branches()? diff --git a/src/plumbing/main.rs b/src/plumbing/main.rs index b3d51c10f4c..9d3a021880a 100644 --- a/src/plumbing/main.rs +++ b/src/plumbing/main.rs @@ -534,6 +534,16 @@ pub fn main() -> Result<()> { }, ), Subcommands::Revision(cmd) => match cmd { + revision::Subcommands::List { spec } => prepare_and_run( + "revision-list", + verbose, + progress, + progress_keep_open, + None, + move |_progress, out, _err| { + core::repository::revision::list(repository(Mode::Lenient)?, spec, out, format) + }, + ), revision::Subcommands::PreviousBranches => prepare_and_run( "revision-previousbranches", verbose, diff --git a/src/plumbing/options.rs b/src/plumbing/options.rs index 921e175a4b4..f6d9a4a98f5 100644 --- a/src/plumbing/options.rs +++ b/src/plumbing/options.rs @@ -222,6 +222,9 @@ pub mod revision { #[derive(Debug, clap::Subcommand)] #[clap(visible_alias = "rev", visible_alias = "r")] pub enum Subcommands { + /// List all commits reachable from the given rev-spec. + #[clap(visible_alias = "l")] + List { spec: std::ffi::OsString }, /// Provide the revision specification like `@~1` to explain. #[clap(visible_alias = "e")] Explain { spec: std::ffi::OsString },