cli: add hard-coded support for specifying previous operation

It's useful for testing to be able to specify some operation that's
not the latest one.

I didn't update the changelog because this feature is mostly for
testing.
This commit is contained in:
Martin von Zweigbergk 2022-04-19 22:51:52 -07:00 committed by spectral
parent 01407f261d
commit f71047c823
3 changed files with 40 additions and 4 deletions

View file

@ -803,6 +803,16 @@ fn resolve_op_for_load(
) -> Result<OpHeads, CommandError> {
if op_str == "@" {
Ok(op_heads_store.get_heads(op_store)?)
} else if op_str == "@-" {
match op_heads_store.get_heads(op_store)? {
OpHeads::Single(current_op) => {
let resolved_op = resolve_single_op(op_store, op_heads_store, &current_op, op_str)?;
Ok(OpHeads::Single(resolved_op))
}
OpHeads::Unresolved { .. } => Err(UserError(format!(
r#"The "{op_str}" expression resolved to more than one operation"#
))),
}
} else {
let operation = resolve_single_op_from_store(op_store, op_heads_store, op_str)?;
Ok(OpHeads::Single(operation))
@ -817,6 +827,14 @@ fn resolve_single_op(
) -> Result<Operation, CommandError> {
if op_str == "@" {
Ok(current_op.clone())
} else if op_str == "@-" {
let parent_ops = current_op.parents();
if parent_ops.len() != 1 {
return Err(UserError(format!(
r#"The "{op_str}" expression resolved to more than one operation"#
)));
}
Ok(parent_ops[0].clone())
} else {
resolve_single_op_from_store(op_store, op_heads_store, op_str)
}

View file

@ -22,13 +22,10 @@ fn test_concurrent_operation_divergence() {
test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
let stdout = test_env.jj_cmd_success(&repo_path, &["op", "log"]);
let op_id_hex = stdout[2..14].to_string();
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "message 1"]);
test_env.jj_cmd_success(
&repo_path,
&["describe", "-m", "message 2", "--at-op", &op_id_hex],
&["describe", "-m", "message 2", "--at-op", "@-"],
);
// We should be informed about the concurrent modification

View file

@ -46,6 +46,10 @@ fn test_op_log() {
@ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
o 0000000000000000000000000000000000000000
"###);
// "@-" resolves to the parent of the head operation
insta::assert_snapshot!(get_log_output(&test_env, &repo_path, "@-"), @r###"
o 0000000000000000000000000000000000000000
"###);
// We get a reasonable message if an invalid operation ID is specified
insta::assert_snapshot!(test_env.jj_cmd_failure(&repo_path, &["log", "--at-op", "foo"]), @r###"Error: Operation ID "foo" is not a valid hexadecimal prefix
@ -59,6 +63,23 @@ fn test_op_log() {
// Empty ID
insta::assert_snapshot!(test_env.jj_cmd_failure(&repo_path, &["log", "--at-op", ""]), @r###"Error: Operation ID "" is not a valid hexadecimal prefix
"###);
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "description 1"]);
test_env.jj_cmd_success(
&repo_path,
&[
"describe",
"-m",
"description 2",
"--at-op",
&add_workspace_id,
],
);
insta::assert_snapshot!(test_env.jj_cmd_failure(&repo_path, &["log", "--at-op", "@-"]), @r###"Error: The "@-" expression resolved to more than one operation
"###);
test_env.jj_cmd_success(&repo_path, &["st"]);
insta::assert_snapshot!(test_env.jj_cmd_failure(&repo_path, &["log", "--at-op", "@-"]), @r###"Error: The "@-" expression resolved to more than one operation
"###);
}
fn get_log_output(test_env: &TestEnvironment, repo_path: &Path, op_id: &str) -> String {