ok/jj
1
0
Fork 0
forked from mirrors/jj
jj/cli/tests/test_next_prev_commands.rs

739 lines
28 KiB
Rust
Raw Normal View History

// Copyright 2023 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 crate::common::{get_stderr_string, get_stdout_string, TestEnvironment};
#[test]
fn test_next_simple() {
// Move from first => second.
// first
// |
// second
// |
// third
//
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");
// Create a simple linear history, which we'll traverse.
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
// Move to `first`
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["next"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: royxmykx fb00d619 (empty) (no description set)
Parent commit : kkmpptxz 30056b0c (empty) third
"###);
}
#[test]
fn test_next_multiple() {
// Move from first => fourth.
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "fourth"]);
test_env.jj_cmd_ok(&repo_path, &["new", "@---"]);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["next", "2"]);
// We should now be the child of the fourth commit.
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: yqosqzyt 50168682 (empty) (no description set)
Parent commit : zsuskuln 9d7e5e99 (empty) fourth
"###);
}
#[test]
fn test_prev_simple() {
// Move @- from third to second.
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ zsuskulnrvyr
kkmpptxzrspx third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["prev"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: royxmykx 6db74f64 (empty) (no description set)
Parent commit : rlvkpnrz 9ed53a4a (empty) second
"###);
}
#[test]
fn test_prev_multiple_without_root() {
// Move @- from fourth to second.
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "fourth"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ mzvwutvlkqwt
zsuskulnrvyr fourth
kkmpptxzrspx third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["prev", "2"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: yqosqzyt 794ffd20 (empty) (no description set)
Parent commit : rlvkpnrz 9ed53a4a (empty) second
"###);
}
#[test]
fn test_next_exceeding_history() {
// Try to step beyond the current repos history.
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
test_env.jj_cmd_ok(&repo_path, &["edit", "-r", "@--"]);
let stderr = test_env.jj_cmd_failure(&repo_path, &["next", "3"]);
// `jj next` beyond existing history fails.
insta::assert_snapshot!(stderr, @r###"
Error: No descendant found 3 commits forward
"###);
}
// The working copy commit is a child of a "fork" with two children on each
// branch.
#[test]
fn test_next_parent_has_multiple_descendants() {
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");
// Setup.
test_env.jj_cmd_ok(&repo_path, &["desc", "-m", "1"]);
test_env.jj_cmd_ok(&repo_path, &["new", "-m", "2"]);
test_env.jj_cmd_ok(&repo_path, &["new", "root()", "-m", "3"]);
test_env.jj_cmd_ok(&repo_path, &["new", "-m", "4"]);
test_env.jj_cmd_ok(&repo_path, &["edit", "description(3)"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
mzvwutvlkqwt 4
@ zsuskulnrvyr 3
kkmpptxzrspx 2
qpvuntsmwlqt 1
zzzzzzzzzzzz
"###);
// --edit is implied since the working copy isn't a leaf commit.
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["next"]);
insta::assert_snapshot!(stdout,@r###""###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: mzvwutvl 1b8531ce (empty) 4
Parent commit : zsuskuln b1394455 (empty) 3
"###);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ mzvwutvlkqwt 4
zsuskulnrvyr 3
kkmpptxzrspx 2
qpvuntsmwlqt 1
zzzzzzzzzzzz
"###);
}
#[test]
fn test_next_with_merge_commit_parent() {
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");
// Setup.
test_env.jj_cmd_ok(&repo_path, &["desc", "-m", "1"]);
test_env.jj_cmd_ok(&repo_path, &["new", "root()", "-m", "2"]);
test_env.jj_cmd_ok(
&repo_path,
&["new", "description(1)", "description(2)", "-m", "3"],
);
test_env.jj_cmd_ok(&repo_path, &["new", "-m", "4"]);
test_env.jj_cmd_ok(&repo_path, &["prev", "0"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ royxmykxtrkr
mzvwutvlkqwt 4
zsuskulnrvyr 3
kkmpptxzrspx 2
qpvuntsmwlqt 1
zzzzzzzzzzzz
"###);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["next"]);
insta::assert_snapshot!(stdout,@r###""###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: vruxwmqv e2cefcb7 (empty) (no description set)
Parent commit : mzvwutvl b54bbdea (empty) 4
"###);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ vruxwmqvtpmx
mzvwutvlkqwt 4
zsuskulnrvyr 3
kkmpptxzrspx 2
qpvuntsmwlqt 1
zzzzzzzzzzzz
"###);
}
#[test]
fn test_next_on_merge_commit() {
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");
// Setup.
test_env.jj_cmd_ok(&repo_path, &["desc", "-m", "1"]);
test_env.jj_cmd_ok(&repo_path, &["new", "root()", "-m", "2"]);
test_env.jj_cmd_ok(
&repo_path,
&["new", "description(1)", "description(2)", "-m", "3"],
);
test_env.jj_cmd_ok(&repo_path, &["new", "-m", "4"]);
test_env.jj_cmd_ok(&repo_path, &["edit", "description(3)"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
mzvwutvlkqwt 4
@ zsuskulnrvyr 3
kkmpptxzrspx 2
qpvuntsmwlqt 1
zzzzzzzzzzzz
"###);
// --edit is implied since the working copy is not a leaf commit.
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["next"]);
insta::assert_snapshot!(stdout,@r###""###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: mzvwutvl b54bbdea (empty) 4
Parent commit : zsuskuln 5542f0b4 (empty) 3
"###);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ mzvwutvlkqwt 4
zsuskulnrvyr 3
kkmpptxzrspx 2
qpvuntsmwlqt 1
zzzzzzzzzzzz
"###);
}
#[test]
fn test_next_fails_on_branching_children_no_stdin() {
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
2024-03-05 05:26:31 +00:00
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
2024-03-05 05:26:31 +00:00
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
// Try to advance the working copy commit.
let assert = test_env.jj_cmd(&repo_path, &["next"]).assert().code(1);
let stderr = test_env.normalize_output(&get_stderr_string(&assert));
insta::assert_snapshot!(stderr,@r###"
Error: Cannot prompt for input since the output is not connected to a terminal
"###);
}
#[test]
fn test_next_fails_on_branching_children_quit_prompt() {
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
2024-03-05 05:26:31 +00:00
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
2024-03-05 05:26:31 +00:00
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
// Try to advance the working copy commit.
let assert = test_env
.jj_cmd_stdin(&repo_path, &["next"], "q\n")
.assert()
.code(1);
let stdout = test_env.normalize_output(&get_stdout_string(&assert));
let stderr = test_env.normalize_output(&get_stderr_string(&assert));
insta::assert_snapshot!(stdout,@r###"
ambiguous next commit, choose one to target:
1: zsuskuln 5f24490d (empty) third
2: rlvkpnrz 9ed53a4a (empty) second
q: quit the prompt
enter the index of the commit you want to target:
"###);
insta::assert_snapshot!(stderr,@r###"
Error: ambiguous target commit
"###);
}
#[test]
fn test_next_choose_branching_child() {
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
2024-03-05 05:26:31 +00:00
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
2024-03-05 05:26:31 +00:00
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "fourth"]);
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
// Advance the working copy commit.
let (stdout, stderr) = test_env.jj_cmd_stdin_ok(&repo_path, &["next"], "2\n");
insta::assert_snapshot!(stdout,@r###"
ambiguous next commit, choose one to target:
1: royxmykx d00fe885 (empty) fourth
2: zsuskuln 5f24490d (empty) third
3: rlvkpnrz 9ed53a4a (empty) second
q: quit the prompt
enter the index of the commit you want to target:
"###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: yostqsxw 5c8fa96d (empty) (no description set)
Parent commit : zsuskuln 5f24490d (empty) third
"###);
}
#[test]
fn test_prev_on_merge_commit() {
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, &["desc", "-m", "first"]);
test_env.jj_cmd_ok(&repo_path, &["branch", "c", "left"]);
test_env.jj_cmd_ok(&repo_path, &["new", "root()", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["branch", "c", "right"]);
test_env.jj_cmd_ok(&repo_path, &["new", "left", "right"]);
// Check that the graph looks the way we expect.
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ royxmykxtrkr
zsuskulnrvyr right second
qpvuntsmwlqt left first
zzzzzzzzzzzz
"###);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["prev"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr,@r###"
Working copy now at: vruxwmqv 41658cf4 (empty) (no description set)
Parent commit : zzzzzzzz 00000000 (empty) (no description set)
"###);
test_env.jj_cmd_ok(&repo_path, &["undo"]);
let (stdout, stderr) = test_env.jj_cmd_stdin_ok(&repo_path, &["prev", "--edit"], "2\n");
insta::assert_snapshot!(stdout, @r###"
ambiguous prev commit, choose one to target:
1: zsuskuln b0d21db3 right | (empty) second
2: qpvuntsm fa15625b left | (empty) first
q: quit the prompt
enter the index of the commit you want to target:
"###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: qpvuntsm fa15625b left | (empty) first
Parent commit : zzzzzzzz 00000000 (empty) (no description set)
"###);
}
#[test]
fn test_prev_on_merge_commit_with_parent_merge() {
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, &["desc", "-m", "x"]);
test_env.jj_cmd_ok(&repo_path, &["new", "root()", "-m", "y"]);
test_env.jj_cmd_ok(
&repo_path,
&["new", "description(x)", "description(y)", "-m", "z"],
);
test_env.jj_cmd_ok(&repo_path, &["new", "root()", "-m", "1"]);
test_env.jj_cmd_ok(
&repo_path,
&["new", "description(z)", "description(1)", "-m", "M"],
);
// Check that the graph looks the way we expect.
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ royxmykxtrkr M
mzvwutvlkqwt 1
zsuskulnrvyr z
kkmpptxzrspx y
qpvuntsmwlqt x
zzzzzzzzzzzz
"###);
let (stdout, stderr) = test_env.jj_cmd_stdin_ok(&repo_path, &["prev"], "2\n");
insta::assert_snapshot!(stdout, @r###"
ambiguous prev commit, choose one to target:
1: kkmpptxz 146d5c67 (empty) y
2: qpvuntsm 6799aaa2 (empty) x
3: zzzzzzzz 00000000 (empty) (no description set)
q: quit the prompt
enter the index of the commit you want to target:
"###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: vruxwmqv e5a6794c (empty) (no description set)
Parent commit : qpvuntsm 6799aaa2 (empty) x
"###);
test_env.jj_cmd_ok(&repo_path, &["undo"]);
let (stdout, stderr) = test_env.jj_cmd_stdin_ok(&repo_path, &["prev", "--edit"], "2\n");
insta::assert_snapshot!(stdout, @r###"
ambiguous prev commit, choose one to target:
1: mzvwutvl 89b8a355 (empty) 1
2: zsuskuln a83fc061 (empty) z
q: quit the prompt
enter the index of the commit you want to target:
"###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: zsuskuln a83fc061 (empty) z
Parent commit : qpvuntsm 6799aaa2 (empty) x
Parent commit : kkmpptxz 146d5c67 (empty) y
"###);
}
#[test]
fn test_prev_prompts_on_multiple_parents() {
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", "first"]);
2024-03-05 05:26:31 +00:00
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["new", "@--"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
// Create a merge commit, which has two parents.
test_env.jj_cmd_ok(&repo_path, &["new", "all:@--+"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "merge"]);
// Check that the graph looks the way we expect.
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ vruxwmqvtpmx
yqosqzytrlsw merge
qpvuntsmwlqt first
kkmpptxzrspx second
mzvwutvlkqwt third
zzzzzzzzzzzz
"###);
// Move @ backwards.
let (stdout, stderr) = test_env.jj_cmd_stdin_ok(&repo_path, &["prev"], "3\n");
insta::assert_snapshot!(stdout,@r###"
ambiguous prev commit, choose one to target:
1: mzvwutvl bc4f4fe3 (empty) third
2: kkmpptxz b0d21db3 (empty) second
3: qpvuntsm fa15625b (empty) first
q: quit the prompt
enter the index of the commit you want to target:
"###);
insta::assert_snapshot!(stderr,@r###"
Working copy now at: znkkpsqq 07b409e8 (empty) (no description set)
Parent commit : qpvuntsm fa15625b (empty) first
"###);
}
#[test]
fn test_prev_beyond_root_fails() {
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "fourth"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ mzvwutvlkqwt
zsuskulnrvyr fourth
kkmpptxzrspx third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
// @- is at "fourth", and there is no parent 5 commits behind it.
let stderr = test_env.jj_cmd_failure(&repo_path, &["prev", "5"]);
insta::assert_snapshot!(stderr,@r###"
Error: No ancestor found 5 commits back
"###);
}
#[test]
fn test_prev_editing() {
// Edit the third commit.
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "fourth"]);
// Edit the "fourth" commit, which becomes the leaf.
test_env.jj_cmd_ok(&repo_path, &["edit", "@-"]);
// Check that the graph looks the way we expect.
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ zsuskulnrvyr fourth
kkmpptxzrspx third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["prev", "--edit"]);
insta::assert_snapshot!(stdout, @r"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: kkmpptxz 30056b0c (empty) third
Parent commit : rlvkpnrz 9ed53a4a (empty) second
"###);
// --edit is implied when already editing a non-head commit
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["prev"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: rlvkpnrz 9ed53a4a (empty) second
Parent commit : qpvuntsm fa15625b (empty) first
"###);
}
#[test]
fn test_next_editing() {
// Edit the second commit.
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", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "fourth"]);
test_env.jj_cmd_ok(&repo_path, &["edit", "@---"]);
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["next", "--edit"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: kkmpptxz 30056b0c (empty) third
Parent commit : rlvkpnrz 9ed53a4a (empty) second
"###);
// --edit is implied when already editing a non-head commit
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["next"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @r###"
Working copy now at: zsuskuln 9d7e5e99 (empty) fourth
Parent commit : kkmpptxz 30056b0c (empty) third
"###);
}
#[test]
fn test_prev_conflict() {
// Make the first commit our new parent.
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
let file_path = repo_path.join("content.txt");
std::fs::write(&file_path, "first").unwrap();
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "first"]);
std::fs::write(&file_path, "second").unwrap();
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
// Create a conflict in the first commit, where we'll jump to.
test_env.jj_cmd_ok(&repo_path, &["edit", "description(first)"]);
std::fs::write(&file_path, "first+1").unwrap();
test_env.jj_cmd_ok(&repo_path, &["new", "description(third)"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "fourth"]);
// Test the setup
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ yqosqzytrlsw conflict
× royxmykxtrkr conflict fourth
× kkmpptxzrspx conflict third
× rlvkpnrzqnoo conflict second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
test_env.jj_cmd_ok(&repo_path, &["prev", "--conflict"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ yostqsxwqrlt conflict
× royxmykxtrkr conflict fourth
× kkmpptxzrspx conflict third
× rlvkpnrzqnoo conflict second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
}
#[test]
fn test_prev_conflict_editing() {
// Edit the third commit.
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
let file_path = repo_path.join("content.txt");
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
std::fs::write(&file_path, "second").unwrap();
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
// Create a conflict in the third commit, where we'll jump to.
test_env.jj_cmd_ok(&repo_path, &["edit", "description(first)"]);
std::fs::write(&file_path, "first text").unwrap();
test_env.jj_cmd_ok(&repo_path, &["new", "description(third)"]);
// Test the setup
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ royxmykxtrkr conflict
× kkmpptxzrspx conflict third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
test_env.jj_cmd_ok(&repo_path, &["prev", "--conflict", "--edit"]);
// We now should be editing the third commit.
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ kkmpptxzrspx conflict third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
}
#[test]
fn test_next_conflict() {
// There is a conflict in the third commit, so after next it should be the new
// parent.
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
let file_path = repo_path.join("content.txt");
std::fs::write(&file_path, "first").unwrap();
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "first"]);
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
// Create a conflict in the third commit.
std::fs::write(&file_path, "third").unwrap();
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "third"]);
test_env.jj_cmd_ok(&repo_path, &["new", "description(first)"]);
std::fs::write(&file_path, "first v2").unwrap();
test_env.jj_cmd_ok(&repo_path, &["squash", "--into", "description(third)"]);
// Test the setup
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ royxmykxtrkr
× kkmpptxzrspx conflict third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
test_env.jj_cmd_ok(&repo_path, &["next", "--conflict"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ vruxwmqvtpmx conflict
× kkmpptxzrspx conflict third
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
}
#[test]
fn test_next_conflict_editing() {
// There is a conflict in the third commit, so after next it should be our
// working copy.
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
let file_path = repo_path.join("content.txt");
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "first"]);
std::fs::write(&file_path, "second").unwrap();
test_env.jj_cmd_ok(&repo_path, &["commit", "-m", "second"]);
// Create a conflict in the third commit.
std::fs::write(&file_path, "third").unwrap();
test_env.jj_cmd_ok(&repo_path, &["edit", "description(second)"]);
std::fs::write(&file_path, "modified second").unwrap();
test_env.jj_cmd_ok(&repo_path, &["edit", "@-"]);
// Test the setup
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
× kkmpptxzrspx conflict
rlvkpnrzqnoo second
@ qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
test_env.jj_cmd_ok(&repo_path, &["next", "--conflict", "--edit"]);
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ kkmpptxzrspx conflict
rlvkpnrzqnoo second
qpvuntsmwlqt first
zzzzzzzzzzzz
"###);
}
#[test]
fn test_next_conflict_head() {
// When editing a head with conflicts, `jj next --conflict [--edit]` errors out.
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["init", "repo", "--git"]);
let repo_path = test_env.env_root().join("repo");
let file_path = repo_path.join("file");
std::fs::write(&file_path, "first").unwrap();
test_env.jj_cmd_ok(&repo_path, &["new"]);
std::fs::write(&file_path, "second").unwrap();
test_env.jj_cmd_ok(&repo_path, &["abandon", "@-"]);
// Test the setup
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
@ rlvkpnrzqnoo conflict
zzzzzzzzzzzz
"###);
let stderr = test_env.jj_cmd_failure(&repo_path, &["next", "--conflict"]);
insta::assert_snapshot!(stderr, @r###"
Error: No descendant found 1 commit forward
"###);
let stderr = test_env.jj_cmd_failure(&repo_path, &["next", "--conflict", "--edit"]);
insta::assert_snapshot!(stderr, @r###"
Error: No descendant found 1 commit forward
"###);
}
fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String {
let template = r#"separate(" ", change_id.short(), local_branches, if(conflict, "conflict"), description)"#;
test_env.jj_cmd_success(cwd, &["log", "-T", template])
}