forked from mirrors/jj
cli: Add an option to diff to output only paths.
This commit is contained in:
parent
f8b87f6499
commit
33ab8d4371
4 changed files with 73 additions and 1 deletions
|
@ -55,6 +55,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
* New command `jj branch move` let you update branches by name pattern or source
|
* New command `jj branch move` let you update branches by name pattern or source
|
||||||
revision.
|
revision.
|
||||||
|
|
||||||
|
* New diff option `jj diff --name-only` allows for easier shell scripting.
|
||||||
|
|
||||||
### Fixed bugs
|
### Fixed bugs
|
||||||
|
|
||||||
## [0.18.0] - 2024-06-05
|
## [0.18.0] - 2024-06-05
|
||||||
|
|
|
@ -48,7 +48,7 @@ const DEFAULT_CONTEXT_LINES: usize = 3;
|
||||||
|
|
||||||
#[derive(clap::Args, Clone, Debug)]
|
#[derive(clap::Args, Clone, Debug)]
|
||||||
#[command(next_help_heading = "Diff Formatting Options")]
|
#[command(next_help_heading = "Diff Formatting Options")]
|
||||||
#[command(group(clap::ArgGroup::new("short-format").args(&["summary", "stat", "types"])))]
|
#[command(group(clap::ArgGroup::new("short-format").args(&["summary", "stat", "types", "name_only"])))]
|
||||||
#[command(group(clap::ArgGroup::new("long-format").args(&["git", "color_words", "tool"])))]
|
#[command(group(clap::ArgGroup::new("long-format").args(&["git", "color_words", "tool"])))]
|
||||||
pub struct DiffFormatArgs {
|
pub struct DiffFormatArgs {
|
||||||
/// For each path, show only whether it was modified, added, or deleted
|
/// For each path, show only whether it was modified, added, or deleted
|
||||||
|
@ -66,6 +66,12 @@ pub struct DiffFormatArgs {
|
||||||
/// Git submodule.
|
/// Git submodule.
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub types: bool,
|
pub types: bool,
|
||||||
|
/// For each path, show only its path
|
||||||
|
///
|
||||||
|
/// Typically useful for shell commands like:
|
||||||
|
/// `jj diff -r @- --name_only | xargs perl -pi -e's/OLD/NEW/g`
|
||||||
|
#[arg(long)]
|
||||||
|
pub name_only: bool,
|
||||||
/// Show a Git-format diff
|
/// Show a Git-format diff
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
pub git: bool,
|
pub git: bool,
|
||||||
|
@ -85,6 +91,7 @@ pub enum DiffFormat {
|
||||||
Summary,
|
Summary,
|
||||||
Stat,
|
Stat,
|
||||||
Types,
|
Types,
|
||||||
|
NameOnly,
|
||||||
Git { context: usize },
|
Git { context: usize },
|
||||||
ColorWords { context: usize },
|
ColorWords { context: usize },
|
||||||
Tool(Box<ExternalMergeTool>),
|
Tool(Box<ExternalMergeTool>),
|
||||||
|
@ -126,6 +133,7 @@ fn diff_formats_from_args(
|
||||||
let mut formats = [
|
let mut formats = [
|
||||||
(args.summary, DiffFormat::Summary),
|
(args.summary, DiffFormat::Summary),
|
||||||
(args.types, DiffFormat::Types),
|
(args.types, DiffFormat::Types),
|
||||||
|
(args.name_only, DiffFormat::NameOnly),
|
||||||
(
|
(
|
||||||
args.git,
|
args.git,
|
||||||
DiffFormat::Git {
|
DiffFormat::Git {
|
||||||
|
@ -176,6 +184,7 @@ fn default_diff_format(
|
||||||
match name.as_ref() {
|
match name.as_ref() {
|
||||||
"summary" => Ok(DiffFormat::Summary),
|
"summary" => Ok(DiffFormat::Summary),
|
||||||
"types" => Ok(DiffFormat::Types),
|
"types" => Ok(DiffFormat::Types),
|
||||||
|
"name-only" => Ok(DiffFormat::NameOnly),
|
||||||
"git" => Ok(DiffFormat::Git {
|
"git" => Ok(DiffFormat::Git {
|
||||||
context: num_context_lines.unwrap_or(DEFAULT_CONTEXT_LINES),
|
context: num_context_lines.unwrap_or(DEFAULT_CONTEXT_LINES),
|
||||||
}),
|
}),
|
||||||
|
@ -251,6 +260,10 @@ impl<'a> DiffRenderer<'a> {
|
||||||
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
show_types(formatter, tree_diff, path_converter)?;
|
show_types(formatter, tree_diff, path_converter)?;
|
||||||
}
|
}
|
||||||
|
DiffFormat::NameOnly => {
|
||||||
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
|
show_names(formatter, tree_diff, path_converter)?;
|
||||||
|
}
|
||||||
DiffFormat::Git { context } => {
|
DiffFormat::Git { context } => {
|
||||||
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
let tree_diff = from_tree.diff_stream(to_tree, matcher);
|
||||||
show_git_diff(repo, formatter, *context, tree_diff)?;
|
show_git_diff(repo, formatter, *context, tree_diff)?;
|
||||||
|
@ -1105,3 +1118,17 @@ fn diff_summary_char(value: &MergedTreeValue) -> char {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn show_names(
|
||||||
|
formatter: &mut dyn Formatter,
|
||||||
|
mut tree_diff: TreeDiffStream,
|
||||||
|
path_converter: &RepoPathUiConverter,
|
||||||
|
) -> io::Result<()> {
|
||||||
|
async {
|
||||||
|
while let Some((repo_path, _)) = tree_diff.next().await {
|
||||||
|
writeln!(formatter, "{}", path_converter.format_file_path(&repo_path))?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
.block_on()
|
||||||
|
}
|
||||||
|
|
|
@ -614,6 +614,9 @@ With the `--from` and/or `--to` options, shows the difference from/to the given
|
||||||
* `--types` — For each path, show only its type before and after
|
* `--types` — For each path, show only its type before and after
|
||||||
|
|
||||||
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
||||||
|
* `--name-only` — For each path, show only its path
|
||||||
|
|
||||||
|
Typically useful for shell commands like: `jj diff -r @- --name_only | xargs perl -pi -e's/OLD/NEW/g`
|
||||||
* `--git` — Show a Git-format diff
|
* `--git` — Show a Git-format diff
|
||||||
* `--color-words` — Show a word-level diff with changes indicated only by color
|
* `--color-words` — Show a word-level diff with changes indicated only by color
|
||||||
* `--tool <TOOL>` — Generate diff by external command
|
* `--tool <TOOL>` — Generate diff by external command
|
||||||
|
@ -1038,6 +1041,9 @@ This excludes changes from other commits by temporarily rebasing `--from` onto `
|
||||||
* `--types` — For each path, show only its type before and after
|
* `--types` — For each path, show only its type before and after
|
||||||
|
|
||||||
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
||||||
|
* `--name-only` — For each path, show only its path
|
||||||
|
|
||||||
|
Typically useful for shell commands like: `jj diff -r @- --name_only | xargs perl -pi -e's/OLD/NEW/g`
|
||||||
* `--git` — Show a Git-format diff
|
* `--git` — Show a Git-format diff
|
||||||
* `--color-words` — Show a word-level diff with changes indicated only by color
|
* `--color-words` — Show a word-level diff with changes indicated only by color
|
||||||
* `--tool <TOOL>` — Generate diff by external command
|
* `--tool <TOOL>` — Generate diff by external command
|
||||||
|
@ -1076,6 +1082,9 @@ Spans of revisions that are not included in the graph per `--revisions` are rend
|
||||||
* `--types` — For each path, show only its type before and after
|
* `--types` — For each path, show only its type before and after
|
||||||
|
|
||||||
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
||||||
|
* `--name-only` — For each path, show only its path
|
||||||
|
|
||||||
|
Typically useful for shell commands like: `jj diff -r @- --name_only | xargs perl -pi -e's/OLD/NEW/g`
|
||||||
* `--git` — Show a Git-format diff
|
* `--git` — Show a Git-format diff
|
||||||
* `--color-words` — Show a word-level diff with changes indicated only by color
|
* `--color-words` — Show a word-level diff with changes indicated only by color
|
||||||
* `--tool <TOOL>` — Generate diff by external command
|
* `--tool <TOOL>` — Generate diff by external command
|
||||||
|
@ -1185,6 +1194,9 @@ Name is derived from Merciual's obsolescence markers.
|
||||||
* `--types` — For each path, show only its type before and after
|
* `--types` — For each path, show only its type before and after
|
||||||
|
|
||||||
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
||||||
|
* `--name-only` — For each path, show only its path
|
||||||
|
|
||||||
|
Typically useful for shell commands like: `jj diff -r @- --name_only | xargs perl -pi -e's/OLD/NEW/g`
|
||||||
* `--git` — Show a Git-format diff
|
* `--git` — Show a Git-format diff
|
||||||
* `--color-words` — Show a word-level diff with changes indicated only by color
|
* `--color-words` — Show a word-level diff with changes indicated only by color
|
||||||
* `--tool <TOOL>` — Generate diff by external command
|
* `--tool <TOOL>` — Generate diff by external command
|
||||||
|
@ -1592,6 +1604,9 @@ Show commit description and changes in a revision
|
||||||
* `--types` — For each path, show only its type before and after
|
* `--types` — For each path, show only its type before and after
|
||||||
|
|
||||||
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
The diff is shown as two letters. The first letter indicates the type before and the second letter indicates the type after. '-' indicates that the path was not present, 'F' represents a regular file, `L' represents a symlink, 'C' represents a conflict, and 'G' represents a Git submodule.
|
||||||
|
* `--name-only` — For each path, show only its path
|
||||||
|
|
||||||
|
Typically useful for shell commands like: `jj diff -r @- --name_only | xargs perl -pi -e's/OLD/NEW/g`
|
||||||
* `--git` — Show a Git-format diff
|
* `--git` — Show a Git-format diff
|
||||||
* `--color-words` — Show a word-level diff with changes indicated only by color
|
* `--color-words` — Show a word-level diff with changes indicated only by color
|
||||||
* `--tool <TOOL>` — Generate diff by external command
|
* `--tool <TOOL>` — Generate diff by external command
|
||||||
|
|
|
@ -290,6 +290,34 @@ fn test_diff_types() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_diff_name_only() {
|
||||||
|
let test_env = TestEnvironment::default();
|
||||||
|
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
|
||||||
|
let repo_path = test_env.env_root().join("repo");
|
||||||
|
|
||||||
|
test_env.jj_cmd_ok(&repo_path, &["new"]);
|
||||||
|
std::fs::write(repo_path.join("deleted"), "d").unwrap();
|
||||||
|
std::fs::write(repo_path.join("modified"), "m").unwrap();
|
||||||
|
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["diff", "--name-only"]), @r###"
|
||||||
|
deleted
|
||||||
|
modified
|
||||||
|
"###);
|
||||||
|
test_env.jj_cmd_ok(&repo_path, &["commit", "-mfirst"]);
|
||||||
|
std::fs::remove_file(repo_path.join("deleted")).unwrap();
|
||||||
|
std::fs::write(repo_path.join("modified"), "mod").unwrap();
|
||||||
|
std::fs::write(repo_path.join("added"), "add").unwrap();
|
||||||
|
std::fs::create_dir(repo_path.join("sub")).unwrap();
|
||||||
|
std::fs::write(repo_path.join("sub/added"), "sub/add").unwrap();
|
||||||
|
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["diff", "--name-only"]).replace('\\', "/"),
|
||||||
|
@r###"
|
||||||
|
added
|
||||||
|
deleted
|
||||||
|
modified
|
||||||
|
sub/added
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_diff_bad_args() {
|
fn test_diff_bad_args() {
|
||||||
let test_env = TestEnvironment::default();
|
let test_env = TestEnvironment::default();
|
||||||
|
|
Loading…
Reference in a new issue