forked from mirrors/jj
log: add -p/--patch option to show diff along with commit meta data
"log -p | less" is the option I often use with hg/git to find interesting bits from the changelog, and I think it's also valid with jj. Unlike "hg log -p --stat", "jj log -p --summary" does not show both diff summary and patch to reflect the internal structure. This behavoir is arguable and may be changed later. The logic of show_patch() is extracted from cmd_show().
This commit is contained in:
parent
9923bab3ba
commit
a7e3269ed8
3 changed files with 118 additions and 1 deletions
|
@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
operation rebased A as A', then B would be automatically rebased on top of
|
||||
A'). See #111 for more examples.
|
||||
|
||||
* `jj log` now accepts `-p`/`--patch` option.
|
||||
|
||||
## [0.3.3] - 2022-03-16
|
||||
|
||||
No changes, only trying to get the automated build to work.
|
||||
|
|
|
@ -1067,6 +1067,11 @@ struct LogArgs {
|
|||
/// documented and is likely to change)
|
||||
#[clap(long, short = 'T')]
|
||||
template: Option<String>,
|
||||
/// Show patch
|
||||
#[clap(long, short = 'p')]
|
||||
patch: bool,
|
||||
#[clap(flatten)]
|
||||
format: DiffFormat,
|
||||
}
|
||||
|
||||
/// Show how a change has evolved
|
||||
|
@ -2663,6 +2668,7 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
|
|||
|
||||
let revset_expression = workspace_command.parse_revset(ui, &args.revisions)?;
|
||||
let repo = workspace_command.repo();
|
||||
let workspace_root = workspace_command.workspace_root();
|
||||
let workspace_id = workspace_command.workspace_id();
|
||||
let checkout_id = repo.view().get_checkout(&workspace_id);
|
||||
let revset = revset_expression.evaluate(repo.as_repo_ref(), Some(&workspace_id))?;
|
||||
|
@ -2710,6 +2716,7 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
|
|||
}
|
||||
let mut buffer = vec![];
|
||||
let commit_id = index_entry.commit_id();
|
||||
let commit = store.get_commit(&commit_id).unwrap();
|
||||
let is_checkout = Some(&commit_id) == checkout_id;
|
||||
{
|
||||
let writer = Box::new(&mut buffer);
|
||||
|
@ -2717,7 +2724,6 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
|
|||
if is_checkout {
|
||||
formatter.add_label("checkout".to_string())?;
|
||||
}
|
||||
let commit = store.get_commit(&commit_id).unwrap();
|
||||
template.format(&commit, formatter.as_mut())?;
|
||||
if is_checkout {
|
||||
formatter.remove_label()?;
|
||||
|
@ -2726,6 +2732,18 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
|
|||
if !buffer.ends_with(b"\n") {
|
||||
buffer.push(b'\n');
|
||||
}
|
||||
if args.patch {
|
||||
let writer = Box::new(&mut buffer);
|
||||
let mut formatter = ui.new_formatter(writer);
|
||||
show_patch(
|
||||
ui,
|
||||
formatter.as_mut(),
|
||||
repo,
|
||||
&commit,
|
||||
workspace_root,
|
||||
&args.format,
|
||||
)?;
|
||||
}
|
||||
let node_symbol = if is_checkout { b"@" } else { b"o" };
|
||||
graph.add_node(
|
||||
&index_entry.position(),
|
||||
|
@ -2738,12 +2756,32 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
|
|||
for index_entry in revset.iter() {
|
||||
let commit = store.get_commit(&index_entry.commit_id()).unwrap();
|
||||
template.format(&commit, formatter)?;
|
||||
// TODO: should --summary (without --patch) show diff summary as in hg log
|
||||
// --stat?
|
||||
if args.patch {
|
||||
show_patch(ui, formatter, repo, &commit, workspace_root, &args.format)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn show_patch(
|
||||
ui: &Ui,
|
||||
formatter: &mut dyn Formatter,
|
||||
repo: &Arc<ReadonlyRepo>,
|
||||
commit: &Commit,
|
||||
workspace_root: &Path,
|
||||
args: &DiffFormat,
|
||||
) -> Result<(), CommandError> {
|
||||
let parents = commit.parents();
|
||||
let from_tree = merge_commit_trees(repo.as_repo_ref(), &parents);
|
||||
let to_tree = commit.tree();
|
||||
let diff_iterator = from_tree.diff(&to_tree, &EverythingMatcher);
|
||||
show_diff(ui, formatter, repo, workspace_root, args, diff_iterator)
|
||||
}
|
||||
|
||||
fn cmd_obslog(ui: &mut Ui, command: &CommandHelper, args: &ObslogArgs) -> Result<(), CommandError> {
|
||||
let mut workspace_command = command.workspace_helper(ui)?;
|
||||
|
||||
|
|
77
tests/test_log_command.rs
Normal file
77
tests/test_log_command.rs
Normal file
|
@ -0,0 +1,77 @@
|
|||
// Copyright 2022 Google LLC
|
||||
//
|
||||
// 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 jujutsu::testutils::TestEnvironment;
|
||||
|
||||
#[test]
|
||||
fn test_log_with_or_without_diff() {
|
||||
let test_env = TestEnvironment::default();
|
||||
test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
|
||||
let repo_path = test_env.env_root().join("repo");
|
||||
|
||||
std::fs::write(repo_path.join("file1"), "foo\n").unwrap();
|
||||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "add a file"]);
|
||||
test_env.jj_cmd_success(&repo_path, &["new", "-m", "a new commit"]);
|
||||
std::fs::write(repo_path.join("file1"), "foo\nbar\n").unwrap();
|
||||
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
@ a new commit
|
||||
o add a file
|
||||
o
|
||||
"###);
|
||||
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "-p"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
@ a new commit
|
||||
| Modified regular file file1:
|
||||
| 1 1: foo
|
||||
| 2: bar
|
||||
o add a file
|
||||
| Added regular file file1:
|
||||
| 1: foo
|
||||
o
|
||||
"###);
|
||||
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "--no-graph"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
a new commit
|
||||
add a file
|
||||
|
||||
"###);
|
||||
|
||||
let stdout = test_env.jj_cmd_success(
|
||||
&repo_path,
|
||||
&["log", "-T", "description", "--no-graph", "-p", "--git"],
|
||||
);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
a new commit
|
||||
diff --git a/file1 b/file1
|
||||
index 257cc5642c...3bd1f0e297 100644
|
||||
--- a/file1
|
||||
+++ b/file1
|
||||
@@ -1,1 +1,2 @@
|
||||
foo
|
||||
+bar
|
||||
add a file
|
||||
diff --git a/file1 b/file1
|
||||
new file mode 100644
|
||||
index 0000000000..257cc5642c
|
||||
--- /dev/null
|
||||
+++ b/file1
|
||||
@@ -1,0 +1,1 @@
|
||||
+foo
|
||||
|
||||
"###);
|
||||
}
|
Loading…
Reference in a new issue