jj/cli/tests/test_operations.rs
Scott Taylor 1eebbe57c0 commit_builder: reset author timestamp on discardable commits
It's common to create empty working-copy commits while using jj, and
currently the author timestamp for a commit is only set when it is first
created. If you create an empty commit, then don't work on a repo for a
few days, and then start working on a new feature without abandoning the
working-copy commit, the author timestamp will remain as the time the
commit was created rather than being updated to the time that work began
or finished.

This commit changes the behavior so that discardable commits (empty
commits with no description) by the current user have their author
timestamps reset when they are rewritten, meaning that the author
timestamp will become finalized whenever a commit is given a description
or becomes non-empty.
2024-06-29 08:35:53 -05:00

515 lines
22 KiB
Rust
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2022 The Jujutsu Authors
//
// 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 std::path::Path;
use itertools::Itertools;
use regex::Regex;
use crate::common::{get_stdout_string, TestEnvironment};
#[test]
fn test_op_log() {
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, &["describe", "-m", "description 0"]);
let stdout = test_env.jj_cmd_success(
&repo_path,
&[
"op",
"log",
"--config-toml",
"template-aliases.'format_time_range(x)' = 'x'",
],
);
insta::assert_snapshot!(&stdout, @r###"
@ c1851f1c3d90 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00
│ describe commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22
│ args: jj describe -m 'description 0'
◉ b51416386f26 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ add workspace 'default'
◉ 9a7d829846af test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ initialize repo
◉ 000000000000 root()
"###);
let op_log_lines = stdout.lines().collect_vec();
let add_workspace_id = op_log_lines[3].split(' ').nth(2).unwrap();
let initialize_repo_id = op_log_lines[5].split(' ').nth(2).unwrap();
// Can load the repo at a specific operation ID
insta::assert_snapshot!(get_log_output(&test_env, &repo_path, initialize_repo_id), @r###"
◉ 0000000000000000000000000000000000000000
"###);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path, add_workspace_id), @r###"
@ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
◉ 0000000000000000000000000000000000000000
"###);
// "@" resolves to the head operation
insta::assert_snapshot!(get_log_output(&test_env, &repo_path, "@"), @r###"
@ 19611c995a342c01f525583e5fcafdd211f6d009
◉ 0000000000000000000000000000000000000000
"###);
// "@-" resolves to the parent of the head operation
insta::assert_snapshot!(get_log_output(&test_env, &repo_path, "@-"), @r###"
@ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
◉ 0000000000000000000000000000000000000000
"###);
insta::assert_snapshot!(
test_env.jj_cmd_failure(&repo_path, &["log", "--at-op", "@----"]), @r###"
Error: The "@----" expression resolved to no operations
"###);
// 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
"###);
test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "description 1"]);
test_env.jj_cmd_ok(
&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]
fn test_op_log_with_custom_symbols() {
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, &["describe", "-m", "description 0"]);
let stdout = test_env.jj_cmd_success(
&repo_path,
&[
"op",
"log",
"--config-toml",
concat!(
"template-aliases.'format_time_range(x)' = 'x'\n",
"templates.op_log_node = 'if(current_operation, \"$\", if(root, \"\", \"\"))'",
),
],
);
insta::assert_snapshot!(&stdout, @r###"
$ c1851f1c3d90 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00
│ describe commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22
│ args: jj describe -m 'description 0'
┝ b51416386f26 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ add workspace 'default'
┝ 9a7d829846af test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ initialize repo
┴ 000000000000 root()
"###);
}
#[test]
fn test_op_log_with_no_template() {
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");
let stderr = test_env.jj_cmd_cli_error(&repo_path, &["op", "log", "-T"]);
insta::assert_snapshot!(stderr, @r###"
error: a value is required for '--template <TEMPLATE>' but none was supplied
For more information, try '--help'.
Hint: The following template aliases are defined:
- builtin_log_comfortable
- builtin_log_compact
- builtin_log_detailed
- builtin_log_node
- builtin_log_node_ascii
- builtin_log_oneline
- builtin_op_log_comfortable
- builtin_op_log_compact
- builtin_op_log_node
- builtin_op_log_node_ascii
- commit_summary_separator
- description_placeholder
- email_placeholder
- name_placeholder
"###);
}
#[test]
fn test_op_log_limit() {
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");
let stdout = test_env.jj_cmd_success(&repo_path, &["op", "log", "-Tdescription", "--limit=1"]);
insta::assert_snapshot!(stdout, @r###"
@ add workspace 'default'
"###);
}
#[test]
fn test_op_log_no_graph() {
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");
let stdout =
test_env.jj_cmd_success(&repo_path, &["op", "log", "--no-graph", "--color=always"]);
insta::assert_snapshot!(stdout, @r###"
b51416386f26 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
add workspace 'default'
9a7d829846af test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
initialize repo
000000000000 root()
"###);
}
#[test]
fn test_op_log_no_graph_null_terminated() {
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, &["commit", "-m", "message1"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "message2"]);
let stdout = test_env.jj_cmd_success(
&repo_path,
&[
"op",
"log",
"--no-graph",
"--template",
r#"id.short(4) ++ "\0""#,
],
);
insta::assert_debug_snapshot!(stdout, @r###""8a30\05cec\0b514\09a7d\00000\0""###);
}
#[test]
fn test_op_log_template() {
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");
let render = |template| test_env.jj_cmd_success(&repo_path, &["op", "log", "-T", template]);
insta::assert_snapshot!(render(r#"id ++ "\n""#), @r###"
@ b51416386f2685fd5493f2b20e8eec3c24a1776d9e1a7cb5ed7e30d2d9c88c0c1e1fe71b0b7358cba60de42533d1228ed9878f2f89817d892c803395ccf9fe92
◉ 9a7d829846af88a2f7a1e348fb46ff58729e49632bc9c6a052aec8501563cb0d10f4a4e6010ffde529f84a2b9b5b3a4c211a889106a41f6c076dfdacc79f6af7
◉ 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
"###);
insta::assert_snapshot!(
render(r#"separate(" ", id.short(5), current_operation, user,
time.start(), time.end(), time.duration()) ++ "\n""#), @r###"
@ b5141 true test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 2001-02-03 04:05:07.000 +07:00 less than a microsecond
◉ 9a7d8 false test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 2001-02-03 04:05:07.000 +07:00 less than a microsecond
◉ 00000 false @ 1970-01-01 00:00:00.000 +00:00 1970-01-01 00:00:00.000 +00:00 less than a microsecond
"###);
// Negative length shouldn't cause panic.
insta::assert_snapshot!(render(r#"id.short(-1) ++ "|""#), @r###"
@ <Error: out of range integral type conversion attempted>|
◉ <Error: out of range integral type conversion attempted>|
◉ <Error: out of range integral type conversion attempted>|
"###);
// Test the default template, i.e. with relative start time and duration. We
// don't generally use that template because it depends on the current time,
// so we need to reset the time range format here.
test_env.add_config(
r#"
[template-aliases]
'format_time_range(time_range)' = 'time_range.start().ago() ++ ", lasted " ++ time_range.duration()'
"#,
);
let regex = Regex::new(r"\d\d years").unwrap();
let stdout = test_env.jj_cmd_success(&repo_path, &["op", "log"]);
insta::assert_snapshot!(regex.replace_all(&stdout, "NN years"), @r###"
@ b51416386f26 test-username@host.example.com NN years ago, lasted less than a microsecond
│ add workspace 'default'
◉ 9a7d829846af test-username@host.example.com NN years ago, lasted less than a microsecond
│ initialize repo
◉ 000000000000 root()
"###);
}
#[test]
fn test_op_log_builtin_templates() {
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");
// Render without graph and append "[EOF]" marker to test line ending
let render = |template| {
test_env.jj_cmd_success(&repo_path, &["op", "log", "-T", template, "--no-graph"])
+ "[EOF]\n"
};
test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "description 0"]);
insta::assert_snapshot!(render(r#"builtin_op_log_compact"#), @r###"
c1851f1c3d90 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00
describe commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22
args: jj describe -m 'description 0'
b51416386f26 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
add workspace 'default'
9a7d829846af test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
initialize repo
000000000000 root()
[EOF]
"###);
insta::assert_snapshot!(render(r#"builtin_op_log_comfortable"#), @r###"
c1851f1c3d90 test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00
describe commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22
args: jj describe -m 'description 0'
b51416386f26 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
add workspace 'default'
9a7d829846af test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
initialize repo
000000000000 root()
[EOF]
"###);
}
#[test]
fn test_op_log_word_wrap() {
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");
let render = |args: &[&str], columns: u32, word_wrap: bool| {
let mut args = args.to_vec();
if word_wrap {
args.push("--config-toml=ui.log-word-wrap=true");
}
let assert = test_env
.jj_cmd(&repo_path, &args)
.env("COLUMNS", columns.to_string())
.assert()
.success()
.stderr("");
get_stdout_string(&assert)
};
// ui.log-word-wrap option works
insta::assert_snapshot!(render(&["op", "log"], 40, false), @r###"
@ b51416386f26 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ add workspace 'default'
◉ 9a7d829846af test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ initialize repo
◉ 000000000000 root()
"###);
insta::assert_snapshot!(render(&["op", "log"], 40, true), @r###"
@ b51416386f26
│ test-username@host.example.com
│ 2001-02-03 04:05:07.000 +07:00 -
│ 2001-02-03 04:05:07.000 +07:00
│ add workspace 'default'
◉ 9a7d829846af
│ test-username@host.example.com
│ 2001-02-03 04:05:07.000 +07:00 -
│ 2001-02-03 04:05:07.000 +07:00
│ initialize repo
◉ 000000000000 root()
"###);
}
#[test]
fn test_op_log_configurable() {
let test_env = TestEnvironment::default();
test_env.add_config(
r#"operation.hostname = "my-hostname"
operation.username = "my-username"
"#,
);
test_env
.jj_cmd(test_env.env_root(), &["git", "init", "repo"])
.env_remove("JJ_OP_HOSTNAME")
.env_remove("JJ_OP_USERNAME")
.assert()
.success();
let repo_path = test_env.env_root().join("repo");
let stdout = test_env.jj_cmd_success(&repo_path, &["op", "log"]);
assert!(stdout.contains("my-username@my-hostname"));
}
#[test]
fn test_op_abandon_ancestors() {
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, &["commit", "-m", "commit 1"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "commit 2"]);
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["op", "log"]), @r###"
@ c2878c428b1c test-username@host.example.com 2001-02-03 04:05:09.000 +07:00 - 2001-02-03 04:05:09.000 +07:00
│ commit 81a4ef3dd421f3184289df1c58bd3a16ea1e3d8e
│ args: jj commit -m 'commit 2'
◉ 5d0ab09ab0fa test-username@host.example.com 2001-02-03 04:05:08.000 +07:00 - 2001-02-03 04:05:08.000 +07:00
│ commit 230dd059e1b059aefc0da06a2e5a7dbf22362f22
│ args: jj commit -m 'commit 1'
◉ b51416386f26 test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ add workspace 'default'
◉ 9a7d829846af test-username@host.example.com 2001-02-03 04:05:07.000 +07:00 - 2001-02-03 04:05:07.000 +07:00
│ initialize repo
◉ 000000000000 root()
"###);
// Abandon old operations. The working-copy operation id should be updated.
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["op", "abandon", "..@-"]);
insta::assert_snapshot!(stderr, @r###"
Abandoned 3 operations and reparented 1 descendant operations.
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["debug", "local-working-copy", "--ignore-working-copy"]), @r###"
Current operation: OperationId("8545e013752445fd845c84eb961dbfbce47e1deb628e4ef20df10f6dc9aae2ef9e47200b0fcc70ca51f050aede05d0fa6dd1db40e20ae740876775738a07d02e")
Current tree: Merge(Resolved(TreeId("4b825dc642cb6eb9a060e54bf8d69288fbee4904")))
"###);
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["op", "log"]), @r###"
@ 8545e0137524 test-username@host.example.com 2001-02-03 04:05:09.000 +07:00 - 2001-02-03 04:05:09.000 +07:00
│ commit 81a4ef3dd421f3184289df1c58bd3a16ea1e3d8e
│ args: jj commit -m 'commit 2'
◉ 000000000000 root()
"###);
// Abandon operation range.
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "commit 3"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "commit 4"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "commit 5"]);
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["op", "abandon", "@---..@-"]);
insta::assert_snapshot!(stderr, @r###"
Abandoned 2 operations and reparented 1 descendant operations.
"###);
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["op", "log"]), @r###"
@ d92d0753399f test-username@host.example.com 2001-02-03 04:05:16.000 +07:00 - 2001-02-03 04:05:16.000 +07:00
│ commit c5f7dd51add0046405055336ef443f882a0a8968
│ args: jj commit -m 'commit 5'
◉ 8545e0137524 test-username@host.example.com 2001-02-03 04:05:09.000 +07:00 - 2001-02-03 04:05:09.000 +07:00
│ commit 81a4ef3dd421f3184289df1c58bd3a16ea1e3d8e
│ args: jj commit -m 'commit 2'
◉ 000000000000 root()
"###);
// Can't abandon the current operation.
let stderr = test_env.jj_cmd_failure(&repo_path, &["op", "abandon", "..@"]);
insta::assert_snapshot!(stderr, @r###"
Error: Cannot abandon the current operation
Hint: Run `jj undo` to revert the current operation, then use `jj op abandon`
"###);
// Can't create concurrent abandoned operations explicitly.
let stderr = test_env.jj_cmd_failure(&repo_path, &["op", "abandon", "--at-op=@-", "@"]);
insta::assert_snapshot!(stderr, @r###"
Error: --at-op is not respected
"###);
// Abandon the current operation by undoing it first.
test_env.jj_cmd_ok(&repo_path, &["undo"]);
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["op", "abandon", "@-"]);
insta::assert_snapshot!(stderr, @r###"
Abandoned 1 operations and reparented 1 descendant operations.
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["debug", "local-working-copy", "--ignore-working-copy"]), @r###"
Current operation: OperationId("0699d720d0cecd80fb7d765c45955708c61b12feb1d7ed9ff2777ae719471f04ffed3c1dc24efdbf94bdb74426065d6fa9a4f0862a89db2c8c8e359eefc45462")
Current tree: Merge(Resolved(TreeId("4b825dc642cb6eb9a060e54bf8d69288fbee4904")))
"###);
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["op", "log"]), @r###"
@ 0699d720d0ce test-username@host.example.com 2001-02-03 04:05:21.000 +07:00 - 2001-02-03 04:05:21.000 +07:00
│ undo operation d92d0753399f732e438bdd88fa7e5214cba2a310d120ec1714028a514c7116bcf04b4a0b26c04dbecf0a917f1d4c8eb05571b8816dd98b0502aaf321e92500b3
│ args: jj undo
◉ 8545e0137524 test-username@host.example.com 2001-02-03 04:05:09.000 +07:00 - 2001-02-03 04:05:09.000 +07:00
│ commit 81a4ef3dd421f3184289df1c58bd3a16ea1e3d8e
│ args: jj commit -m 'commit 2'
◉ 000000000000 root()
"###);
// Abandon empty range.
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["op", "abandon", "@-..@-"]);
insta::assert_snapshot!(stderr, @r###"
Nothing changed.
"###);
insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["op", "log", "-n1"]), @r###"
@ 0699d720d0ce test-username@host.example.com 2001-02-03 04:05:21.000 +07:00 - 2001-02-03 04:05:21.000 +07:00
│ undo operation d92d0753399f732e438bdd88fa7e5214cba2a310d120ec1714028a514c7116bcf04b4a0b26c04dbecf0a917f1d4c8eb05571b8816dd98b0502aaf321e92500b3
│ args: jj undo
"###);
}
#[test]
fn test_op_abandon_without_updating_working_copy() {
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, &["commit", "-m", "commit 1"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "commit 2"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "commit 3"]);
// Abandon without updating the working copy.
let (_stdout, stderr) = test_env.jj_cmd_ok(
&repo_path,
&["op", "abandon", "@-", "--ignore-working-copy"],
);
insta::assert_snapshot!(stderr, @r###"
Abandoned 1 operations and reparented 1 descendant operations.
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["debug", "local-working-copy", "--ignore-working-copy"]), @r###"
Current operation: OperationId("cd2b4690faf20cdc477e90c224f15a1f4d62b4d16d0d515fc0f9c998ff91a971cb114d82075c9a7331f3f94d7188c1f93628b7b93e4ca77ac89435a7b536de1e")
Current tree: Merge(Resolved(TreeId("4b825dc642cb6eb9a060e54bf8d69288fbee4904")))
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["op", "log", "-n1", "--ignore-working-copy"]), @r###"
@ 467d42715f00 test-username@host.example.com 2001-02-03 04:05:10.000 +07:00 - 2001-02-03 04:05:10.000 +07:00
│ commit 220cb0b1b5d1c03cc0d351139d824598bb3c1967
│ args: jj commit -m 'commit 3'
"###);
// The working-copy operation id isn't updated if it differs from the repo.
// It could be updated if the tree matches, but there's no extra logic for
// that.
let (_stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["op", "abandon", "@-"]);
insta::assert_snapshot!(stderr, @r###"
Abandoned 1 operations and reparented 1 descendant operations.
Warning: The working copy operation cd2b4690faf2 is not updated because it differs from the repo 467d42715f00.
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["debug", "local-working-copy", "--ignore-working-copy"]), @r###"
Current operation: OperationId("cd2b4690faf20cdc477e90c224f15a1f4d62b4d16d0d515fc0f9c998ff91a971cb114d82075c9a7331f3f94d7188c1f93628b7b93e4ca77ac89435a7b536de1e")
Current tree: Merge(Resolved(TreeId("4b825dc642cb6eb9a060e54bf8d69288fbee4904")))
"###);
insta::assert_snapshot!(
test_env.jj_cmd_success(&repo_path, &["op", "log", "-n1", "--ignore-working-copy"]), @r###"
@ 050b33d674ff test-username@host.example.com 2001-02-03 04:05:10.000 +07:00 - 2001-02-03 04:05:10.000 +07:00
│ commit 220cb0b1b5d1c03cc0d351139d824598bb3c1967
│ args: jj commit -m 'commit 3'
"###);
}
fn get_log_output(test_env: &TestEnvironment, repo_path: &Path, op_id: &str) -> String {
test_env.jj_cmd_success(
repo_path,
&["log", "-T", "commit_id", "--at-op", op_id, "-r", "all()"],
)
}