just playing with tangled
at diffedit3 99 lines 3.8 kB view raw
1// Copyright 2020 The Jujutsu Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15use jj_lib::rewrite::merge_commit_trees; 16use tracing::instrument; 17 18use crate::cli_util::{print_unmatched_explicit_paths, CommandHelper, RevisionArg}; 19use crate::command_error::CommandError; 20use crate::diff_util::{diff_formats_for, show_diff, DiffFormatArgs}; 21use crate::ui::Ui; 22 23/// Compare file contents between two revisions 24/// 25/// With the `-r` option, which is the default, shows the changes compared to 26/// the parent revision. If there are several parent revisions (i.e., the given 27/// revision is a merge), then they will be merged and the changes from the 28/// result to the given revision will be shown. 29/// 30/// With the `--from` and/or `--to` options, shows the difference from/to the 31/// given revisions. If either is left out, it defaults to the working-copy 32/// commit. For example, `jj diff --from main` shows the changes from "main" 33/// (perhaps a branch name) to the working-copy commit. 34#[derive(clap::Args, Clone, Debug)] 35pub(crate) struct DiffArgs { 36 /// Show changes in this revision, compared to its parent(s) 37 /// 38 /// If the revision is a merge commit, this shows changes *from* the 39 /// automatic merge of the contents of all of its parents *to* the contents 40 /// of the revision itself. 41 #[arg(long, short)] 42 revision: Option<RevisionArg>, 43 /// Show changes from this revision 44 #[arg(long, conflicts_with = "revision")] 45 from: Option<RevisionArg>, 46 /// Show changes to this revision 47 #[arg(long, conflicts_with = "revision")] 48 to: Option<RevisionArg>, 49 /// Restrict the diff to these paths 50 #[arg(value_hint = clap::ValueHint::AnyPath)] 51 paths: Vec<String>, 52 #[command(flatten)] 53 format: DiffFormatArgs, 54} 55 56#[instrument(skip_all)] 57pub(crate) fn cmd_diff( 58 ui: &mut Ui, 59 command: &CommandHelper, 60 args: &DiffArgs, 61) -> Result<(), CommandError> { 62 let workspace_command = command.workspace_helper(ui)?; 63 let from_tree; 64 let to_tree; 65 if args.from.is_some() || args.to.is_some() { 66 let from = 67 workspace_command.resolve_single_rev(args.from.as_ref().unwrap_or(&RevisionArg::AT))?; 68 from_tree = from.tree()?; 69 let to = 70 workspace_command.resolve_single_rev(args.to.as_ref().unwrap_or(&RevisionArg::AT))?; 71 to_tree = to.tree()?; 72 } else { 73 let commit = workspace_command 74 .resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?; 75 let parents = commit.parents(); 76 from_tree = merge_commit_trees(workspace_command.repo().as_ref(), &parents)?; 77 to_tree = commit.tree()? 78 } 79 let fileset_expression = workspace_command.parse_file_patterns(&args.paths)?; 80 let matcher = fileset_expression.to_matcher(); 81 let diff_formats = diff_formats_for(command.settings(), &args.format)?; 82 ui.request_pager(); 83 show_diff( 84 ui, 85 ui.stdout_formatter().as_mut(), 86 &workspace_command, 87 &from_tree, 88 &to_tree, 89 matcher.as_ref(), 90 &diff_formats, 91 )?; 92 print_unmatched_explicit_paths( 93 ui, 94 &workspace_command, 95 &fileset_expression, 96 [&from_tree, &to_tree], 97 )?; 98 Ok(()) 99}