cli: make log accept multiple -rREVISION expressions

For scripting scenario, multiple -r options are easier to construct than
concatenating expressions with ")|(".
This commit is contained in:
Yuya Nishihara 2023-06-29 17:33:57 +09:00
parent 7ad6357c10
commit e601a30b15
2 changed files with 50 additions and 5 deletions

View file

@ -354,7 +354,7 @@ struct LogArgs {
/// or `@ | (remote_branches() | tags()).. | ((remote_branches() | /// or `@ | (remote_branches() | tags()).. | ((remote_branches() |
/// tags())..)-` if it is not set. /// tags())..)-` if it is not set.
#[arg(long, short)] #[arg(long, short)]
revisions: Option<RevisionArg>, revisions: Vec<RevisionArg>,
/// Show commits modifying the given paths /// Show commits modifying the given paths
#[arg(value_hint = clap::ValueHint::AnyPath)] #[arg(value_hint = clap::ValueHint::AnyPath)]
paths: Vec<String>, paths: Vec<String>,
@ -1541,9 +1541,16 @@ fn cmd_status(
fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), CommandError> { fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?; let workspace_command = command.workspace_helper(ui)?;
let default_revset = command.settings().default_revset(); let revset_expression = if args.revisions.is_empty() {
let revset_expression = workspace_command.parse_revset(&command.settings().default_revset())?
workspace_command.parse_revset(args.revisions.as_deref().unwrap_or(&default_revset))?; } else {
let expressions: Vec<_> = args
.revisions
.iter()
.map(|revision_str| workspace_command.parse_revset(revision_str))
.try_collect()?;
RevsetExpression::union_all(&expressions)
};
let repo = workspace_command.repo(); let repo = workspace_command.repo();
let wc_commit_id = workspace_command.get_wc_commit_id(); let wc_commit_id = workspace_command.get_wc_commit_id();
let revset_expression = if !args.paths.is_empty() { let revset_expression = if !args.paths.is_empty() {
@ -1668,7 +1675,7 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
// Check to see if the user might have specified a path when they intended // Check to see if the user might have specified a path when they intended
// to specify a revset. // to specify a revset.
if let (None, [only_path]) = (&args.revisions, args.paths.as_slice()) { if let ([], [only_path]) = (args.revisions.as_slice(), args.paths.as_slice()) {
if only_path == "." && workspace_command.parse_file_path(only_path)?.is_root() { if only_path == "." && workspace_command.parse_file_path(only_path)?.is_root() {
// For users of e.g. Mercurial, where `.` indicates the current commit. // For users of e.g. Mercurial, where `.` indicates the current commit.
writeln!( writeln!(

View file

@ -866,6 +866,44 @@ fn test_default_revset_per_repo() {
); );
} }
#[test]
fn test_multiple_revsets() {
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");
for name in ["foo", "bar", "baz"] {
test_env.jj_cmd_success(&repo_path, &["new", "-m", name]);
test_env.jj_cmd_success(&repo_path, &["branch", "set", name]);
}
// Default revset should be overridden if one or more -r options are specified.
test_env.add_config(r#"revsets.log = "root""#);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["log", "-T", "branches", "-rfoo"]),
@r###"
foo
~
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["log", "-T", "branches", "-rfoo", "-rbar", "-rbaz"]),
@r###"
@ baz
bar
foo
~
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["log", "-T", "branches", "-rfoo", "-rfoo"]),
@r###"
foo
~
"###);
}
#[test] #[test]
fn test_graph_template_color() { fn test_graph_template_color() {
// Test that color codes from a multi-line template don't span the graph lines. // Test that color codes from a multi-line template don't span the graph lines.