Skip to content

Commit

Permalink
Add --context flag for diffs.
Browse files Browse the repository at this point in the history
Allows specifying the number of lines of context to show around diffs.
The logic was already in place, just some plumbing was needed.
  • Loading branch information
algmyr committed Mar 2, 2024
1 parent b926fd8 commit 5650687
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 18 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* `jj branch list` now supports a `--tracked/-t` option which can be used to
show tracked branches only. Omits local Git-tracking branches by default.

* `jj diff/interdiff/obslog` now accept a `--context` flag for the number of
lines of context to show.

### Fixed bugs

* On Windows, symlinks in the repo are now materialized as regular files in the
Expand Down
8 changes: 7 additions & 1 deletion cli/src/commands/obslog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,13 @@ pub(crate) fn cmd_obslog(
with_content_format
.write(formatter, |formatter| template.format(&commit, formatter))?;
if !diff_formats.is_empty() {
show_predecessor_patch(ui, formatter, &workspace_command, &commit, &diff_formats)?;
show_predecessor_patch(
ui,
formatter,
&workspace_command,
&commit,
&diff_formats,
)?;
}
}
}
Expand Down
64 changes: 47 additions & 17 deletions cli/src/diff_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ use crate::merge_tools::{self, ExternalMergeTool};
use crate::text_util;
use crate::ui::Ui;

const DEFAULT_CONTEXT_LINES: usize = 3;

#[derive(clap::Args, Clone, Debug)]
#[command(next_help_heading = "Diff Formatting Options")]
#[command(group(clap::ArgGroup::new("short-format").args(&["summary", "stat", "types"])))]
Expand Down Expand Up @@ -73,15 +75,18 @@ pub struct DiffFormatArgs {
/// Generate diff by external command
#[arg(long)]
pub tool: Option<String>,
/// Number of lines of context to show.
#[arg(long)]
context: Option<usize>,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum DiffFormat {
Summary,
Stat,
Types,
Git,
ColorWords,
Git(usize),
ColorWords(usize),
Tool(Box<ExternalMergeTool>),
}

Expand Down Expand Up @@ -121,8 +126,14 @@ fn diff_formats_from_args(
let mut formats = [
(args.summary, DiffFormat::Summary),
(args.types, DiffFormat::Types),
(args.git, DiffFormat::Git),
(args.color_words, DiffFormat::ColorWords),
(
args.git,
DiffFormat::Git(args.context.unwrap_or(DEFAULT_CONTEXT_LINES)),
),
(
args.color_words,
DiffFormat::ColorWords(args.context.unwrap_or(DEFAULT_CONTEXT_LINES)),
),
(args.stat, DiffFormat::Stat),
]
.into_iter()
Expand Down Expand Up @@ -158,8 +169,8 @@ fn default_diff_format(settings: &UserSettings) -> Result<DiffFormat, config::Co
match name.as_ref() {
"summary" => Ok(DiffFormat::Summary),
"types" => Ok(DiffFormat::Types),
"git" => Ok(DiffFormat::Git),
"color-words" => Ok(DiffFormat::ColorWords),
"git" => Ok(DiffFormat::Git(DEFAULT_CONTEXT_LINES)),
"color-words" => Ok(DiffFormat::ColorWords(DEFAULT_CONTEXT_LINES)),
"stat" => Ok(DiffFormat::Stat),
_ => Err(config::ConfigError::Message(format!(
"invalid diff format: {name}"
Expand Down Expand Up @@ -190,13 +201,13 @@ pub fn show_diff(
let tree_diff = from_tree.diff_stream(to_tree, matcher);
show_types(formatter, workspace_command, tree_diff)?;
}
DiffFormat::Git => {
DiffFormat::Git(num_context_lines) => {
let tree_diff = from_tree.diff_stream(to_tree, matcher);
show_git_diff(formatter, workspace_command, tree_diff)?;
show_git_diff(formatter, workspace_command, *num_context_lines, tree_diff)?;
}
DiffFormat::ColorWords => {
DiffFormat::ColorWords(num_context_lines) => {
let tree_diff = from_tree.diff_stream(to_tree, matcher);
show_color_words_diff(formatter, workspace_command, tree_diff)?;
show_color_words_diff(formatter, workspace_command, *num_context_lines, tree_diff)?;
}
DiffFormat::Tool(tool) => {
merge_tools::generate_diff(ui, formatter.raw(), from_tree, to_tree, matcher, tool)?;
Expand Down Expand Up @@ -231,10 +242,10 @@ pub fn show_patch(
fn show_color_words_diff_hunks(
left: &[u8],
right: &[u8],
num_context_lines: usize,
formatter: &mut dyn Formatter,
) -> io::Result<()> {
const SKIPPED_CONTEXT_LINE: &str = " ...\n";
let num_context_lines = 3;
let mut context = VecDeque::new();
// Have we printed "..." for any skipped context?
let mut skipped_context = false;
Expand Down Expand Up @@ -429,6 +440,7 @@ fn basic_diff_file_type(value: &MaterializedTreeValue) -> &'static str {
pub fn show_color_words_diff(
formatter: &mut dyn Formatter,
workspace_command: &WorkspaceCommandHelper,
num_context_lines: usize,
tree_diff: TreeDiffStream,
) -> Result<(), CommandError> {
formatter.push_label("diff")?;
Expand All @@ -449,7 +461,12 @@ pub fn show_color_words_diff(
} else if right_content.is_binary {
writeln!(formatter.labeled("binary"), " (binary)")?;
} else {
show_color_words_diff_hunks(&[], &right_content.contents, formatter)?;
show_color_words_diff_hunks(
&[],
&right_content.contents,
num_context_lines,
formatter,
)?;
}
} else if right_value.is_present() {
let description = match (&left_value, &right_value) {
Expand Down Expand Up @@ -508,6 +525,7 @@ pub fn show_color_words_diff(
show_color_words_diff_hunks(
&left_content.contents,
&right_content.contents,
num_context_lines,
formatter,
)?;
}
Expand All @@ -523,7 +541,12 @@ pub fn show_color_words_diff(
} else if left_content.is_binary {
writeln!(formatter.labeled("binary"), " (binary)")?;
} else {
show_color_words_diff_hunks(&left_content.contents, &[], formatter)?;
show_color_words_diff_hunks(
&left_content.contents,
&[],
num_context_lines,
formatter,
)?;
}
}
}
Expand Down Expand Up @@ -694,8 +717,9 @@ fn show_unified_diff_hunks(
formatter: &mut dyn Formatter,
left_content: &[u8],
right_content: &[u8],
num_context_lines: usize,
) -> Result<(), CommandError> {
for hunk in unified_diff_hunks(left_content, right_content, 3) {
for hunk in unified_diff_hunks(left_content, right_content, num_context_lines) {
writeln!(
formatter.labeled("hunk_header"),
"@@ -{},{} +{},{} @@",
Expand Down Expand Up @@ -760,6 +784,7 @@ fn materialized_diff_stream<'a>(
pub fn show_git_diff(
formatter: &mut dyn Formatter,
workspace_command: &WorkspaceCommandHelper,
num_context_lines: usize,
tree_diff: TreeDiffStream,
) -> Result<(), CommandError> {
formatter.push_label("diff")?;
Expand All @@ -778,7 +803,7 @@ pub fn show_git_diff(
writeln!(formatter, "--- /dev/null")?;
writeln!(formatter, "+++ b/{path_string}")
})?;
show_unified_diff_hunks(formatter, &[], &right_part.content)?;
show_unified_diff_hunks(formatter, &[], &right_part.content, num_context_lines)?;
} else if right_value.is_present() {
let left_part = git_diff_part(&path, left_value)?;
let right_part = git_diff_part(&path, right_value)?;
Expand All @@ -803,7 +828,12 @@ pub fn show_git_diff(
}
Ok(())
})?;
show_unified_diff_hunks(formatter, &left_part.content, &right_part.content)?;
show_unified_diff_hunks(
formatter,
&left_part.content,
&right_part.content,
num_context_lines,
)?;
} else {
let left_part = git_diff_part(&path, left_value)?;
formatter.with_label("file_header", |formatter| {
Expand All @@ -813,7 +843,7 @@ pub fn show_git_diff(
writeln!(formatter, "--- a/{path_string}")?;
writeln!(formatter, "+++ /dev/null")
})?;
show_unified_diff_hunks(formatter, &left_part.content, &[])?;
show_unified_diff_hunks(formatter, &left_part.content, &[], num_context_lines)?;
}
}
Ok::<(), CommandError>(())
Expand Down
5 changes: 5 additions & 0 deletions cli/tests/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,7 @@ With the `--from` and/or `--to` options, shows the difference from/to the given
Possible values: `true`, `false`
* `--tool <TOOL>` — Generate diff by external command
* `--context <CONTEXT>` — Number of lines of context to show
Expand Down Expand Up @@ -1000,6 +1001,7 @@ This excludes changes from other commits by temporarily rebasing `--from` onto `
Possible values: `true`, `false`
* `--tool <TOOL>` — Generate diff by external command
* `--context <CONTEXT>` — Number of lines of context to show
Expand Down Expand Up @@ -1051,6 +1053,7 @@ Show commit history
Possible values: `true`, `false`
* `--tool <TOOL>` — Generate diff by external command
* `--context <CONTEXT>` — Number of lines of context to show
Expand Down Expand Up @@ -1221,6 +1224,7 @@ Show how a change has evolved as it's been updated, rebased, etc.
Possible values: `true`, `false`
* `--tool <TOOL>` — Generate diff by external command
* `--context <CONTEXT>` — Number of lines of context to show
Expand Down Expand Up @@ -1592,6 +1596,7 @@ Show commit description and changes in a revision
Possible values: `true`, `false`
* `--tool <TOOL>` — Generate diff by external command
* `--context <CONTEXT>` — Number of lines of context to show
Expand Down

0 comments on commit 5650687

Please sign in to comment.