Skip to content

Commit

Permalink
feat!: gix rev resolve --explain (#427)
Browse files Browse the repository at this point in the history
  • Loading branch information
Byron committed Aug 3, 2022
1 parent eb46ad9 commit c5846e0
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 36 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Please see _'Development Status'_ for a listing of all crates and their capabili
* [x] **entries** - display all entries of the aggregated mailmap git would use for substitution
* **revision**
* [x] **explain** - show what would be done while parsing a revision specification like `HEAD~1`
* [x] **parse** - Show which objects a revspec resolves to
* [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.
* **free** - no git repository necessary
* **pack**
Expand Down
30 changes: 3 additions & 27 deletions gitoxide-core/src/repository/revision/mod.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,8 @@
mod explain;
pub use explain::explain;

pub mod parse;
pub use parse::function::parse;
pub mod resolve;
pub use resolve::function::resolve;

mod previous_branches {
use anyhow::Context;
use git_repository as git;

use crate::OutputFormat;

pub fn function(repo: git::Repository, mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
let branches = repo
.head()?
.prior_checked_out_branches()?
.context("The reflog for HEAD is required")?;
match format {
OutputFormat::Human => {
for (name, id) in branches {
writeln!(out, "{} {}", id, name)?;
}
}
#[cfg(feature = "serde1")]
OutputFormat::Json => {
serde_json::to_writer_pretty(&mut out, &branches)?;
}
}
Ok(())
}
}
mod previous_branches;
pub use previous_branches::function as previous_branches;
23 changes: 23 additions & 0 deletions gitoxide-core/src/repository/revision/previous_branches.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
use anyhow::Context;
use git_repository as git;

use crate::OutputFormat;

pub fn function(repo: git::Repository, mut out: impl std::io::Write, format: OutputFormat) -> anyhow::Result<()> {
let branches = repo
.head()?
.prior_checked_out_branches()?
.context("The reflog for HEAD is required")?;
match format {
OutputFormat::Human => {
for (name, id) in branches {
writeln!(out, "{} {}", id, name)?;
}
}
#[cfg(feature = "serde1")]
OutputFormat::Json => {
serde_json::to_writer_pretty(&mut out, &branches)?;
}
}
Ok(())
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,43 @@ use crate::OutputFormat;

pub struct Options {
pub format: OutputFormat,
pub explain: bool,
}

pub(crate) mod function {
use anyhow::bail;
use std::ffi::OsString;

use git_repository as git;

use super::Options;
use crate::repository::revision;
use crate::OutputFormat;

pub fn parse(
pub fn resolve(
mut repo: git::Repository,
specs: Vec<OsString>,
mut out: impl std::io::Write,
Options { format }: Options,
Options { format, explain }: Options,
) -> anyhow::Result<()> {
repo.object_cache_size_if_unset(1024 * 1024);

match format {
OutputFormat::Human => {
for spec in specs {
if explain {
return revision::explain(spec, out);
}
let spec = git::path::os_str_into_bstr(&spec)?;
let spec = repo.rev_parse(spec)?.detach();
writeln!(out, "{spec}")?;
}
}
#[cfg(feature = "serde1")]
OutputFormat::Json => {
if explain {
bail!("Explanations are only for human consumption")
}
serde_json::to_writer_pretty(
&mut out,
&specs
Expand Down
6 changes: 3 additions & 3 deletions src/plumbing/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -532,18 +532,18 @@ pub fn main() -> Result<()> {
None,
move |_progress, out, _err| core::repository::revision::explain(spec, out),
),
revision::Subcommands::Parse { specs } => prepare_and_run(
revision::Subcommands::Resolve { specs, explain } => prepare_and_run(
"revision-parse",
verbose,
progress,
progress_keep_open,
None,
move |_progress, out, _err| {
core::repository::revision::parse(
core::repository::revision::resolve(
repository()?,
specs,
out,
core::repository::revision::parse::Options { format },
core::repository::revision::resolve::Options { format, explain },
)
},
),
Expand Down
11 changes: 8 additions & 3 deletions src/plumbing/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,14 @@ pub mod revision {
/// Provide the revision specification like `@~1` to explain.
Explain { spec: std::ffi::OsString },
/// Try to resolve the given revspec and print the object names.
#[clap(visible_alias = "query")]
Parse {
#[clap(min_values = 1)]
#[clap(visible_alias = "query", visible_alias = "parse")]
Resolve {
/// If set, instead of resolving a rev-spec, explain what would be done for the first spec.
/// Equivalent to the `explain` subcommand.
#[clap(short = 'e', long)]
explain: bool,
/// rev-specs like `@`, `@~1` or `HEAD^2`.
#[clap(required = true)]
specs: Vec<std::ffi::OsString>,
},
/// Return the names and hashes of all previously checked-out branches.
Expand Down

0 comments on commit c5846e0

Please sign in to comment.