114 lines · 3.9 KB · Rust
RawDownload
// Copyright 2020 The Jujutsu Authors//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License. use clap_complete::ArgValueCandidates;use clap_complete::ArgValueCompleter;use futures::StreamExt as _;use futures::TryStreamExt as _;use futures::stream;use jj_lib::matchers::EverythingMatcher;use tracing::instrument; use crate::cli_util::CommandHelper;use crate::cli_util::RevisionArg;use crate::command_error::CommandError;use crate::complete;use crate::diff_util::DiffFormatArgs;use crate::ui::Ui; /// Show revision metadata and diff#[derive(clap::Args, Clone, Debug)]#[command(mut_arg("ignore_all_space", |a| a.short('w')))]#[command(mut_arg("ignore_space_change", |a| a.short('b')))]pub(crate) struct ShowArgs {    /// Show changes in these revisions, compared to their parent(s)    /// [default: @] [aliases: -r]    #[arg(value_name = "REVSETS")]    #[arg(add = ArgValueCompleter::new(complete::revset_expression_all))]    revisions_pos: Vec<RevisionArg>,     #[arg(short = 'r', hide = true, value_name = "REVSETS")]    #[arg(add = ArgValueCompleter::new(complete::revset_expression_all))]    revisions_opt: Vec<RevisionArg>,     /// Show revisions in the opposite order (older revisions first)    #[arg(long)]    reversed: bool,     /// Render each revision using the given template    ///    /// You can specify arbitrary template expressions using the    /// [built-in keywords]. See [`jj help -k templates`] for more information.    ///    /// [built-in keywords]:    ///     https://docs.jj-vcs.dev/latest/templates/#commit-keywords    ///    /// [`jj help -k templates`]:    ///     https://docs.jj-vcs.dev/latest/templates/    #[arg(long, short = 'T')]    #[arg(add = ArgValueCandidates::new(complete::template_aliases))]    template: Option<String>,     #[command(flatten)]    format: DiffFormatArgs,     /// Do not show the patch    #[arg(long, conflicts_with = "DiffFormatArgs")]    no_patch: bool,} #[instrument(skip_all)]pub(crate) async fn cmd_show(    ui: &mut Ui,    command: &CommandHelper,    args: &ShowArgs,) -> Result<(), CommandError> {    let workspace_command = command.workspace_helper(ui).await?;     let target_expr = if args.revisions_pos.is_empty() && args.revisions_opt.is_empty() {        workspace_command.parse_revset(ui, &RevisionArg::AT)?    } else {        workspace_command            .parse_union_revsets(ui, &[&*args.revisions_pos, &*args.revisions_opt].concat())?    };    let template_string = match &args.template {        Some(value) => value.clone(),        None => workspace_command.settings().get_string("templates.show")?,    };    let template = workspace_command        .parse_commit_template(ui, &template_string)?        .labeled(["show", "commit"]);    let diff_renderer = workspace_command.diff_renderer_for(&args.format)?;     let mut commit_stream = target_expr.evaluate_to_commits()?;    if args.reversed {        let commits: Vec<_> = commit_stream.try_collect().await?;        commit_stream = stream::iter(commits.into_iter().rev().map(Ok)).boxed_local();    }     ui.request_pager();    let mut formatter = ui.stdout_formatter();    let formatter = formatter.as_mut();     while let Some(commit) = commit_stream.try_next().await? {        template.format(&commit, formatter)?;         if !args.no_patch {            diff_renderer                .show_patch(ui, formatter, &commit, &EverythingMatcher, ui.term_width())                .await?;        }    }    Ok(())}