// 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 crate::common::CommandOutput;use crate::common::TestEnvironment;use crate::common::TestWorkDir;use crate::common::create_commit;use crate::common::create_commit_with_files; #[test]fn test_rebase_invalid() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); // Missing destination let output = work_dir.run_jj(["rebase"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the following required arguments were not provided: <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> Usage: jj rebase <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -r and -s let output = work_dir.run_jj(["rebase", "-r", "a", "-s", "a", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--revisions <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -b and -s let output = work_dir.run_jj(["rebase", "-b", "a", "-s", "a", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--branch <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --branch <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -o and --after let output = work_dir.run_jj(["rebase", "-r", "a", "-o", "b", "--after", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--onto <REVSETS>' cannot be used with '--insert-after <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -o and --before let output = work_dir.run_jj(["rebase", "-r", "a", "-o", "b", "--before", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--onto <REVSETS>' cannot be used with '--insert-before <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Rebase onto self with -r let output = work_dir.run_jj(["rebase", "-r", "a", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: Cannot rebase 7d980be7a1d4 onto itself [EOF] [exit status: 1] "); // Rebase root with -r let output = work_dir.run_jj(["rebase", "-r", "root()", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: The root commit 000000000000 is immutable [EOF] [exit status: 1] "); // Rebase onto descendant with -s let output = work_dir.run_jj(["rebase", "-s", "a", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: Cannot rebase 7d980be7a1d4 onto descendant 123b4d91f6e5 [EOF] [exit status: 1] "); // Rebase onto itself with -s let output = work_dir.run_jj(["rebase", "-s", "a", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: Cannot rebase 7d980be7a1d4 onto itself [EOF] [exit status: 1] ");} #[test]fn test_rebase_empty_sets() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); let output = work_dir.run_jj(["rebase", "-r=none()", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] "); let output = work_dir.run_jj(["rebase", "-s=none()", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] "); let output = work_dir.run_jj(["rebase", "-b=none()", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] "); // Empty because "b..a" is empty let output = work_dir.run_jj(["rebase", "-b=a", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] ");} #[test]fn test_rebase_bookmark() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &["b"]); create_commit(&work_dir, "d", &["b"]); create_commit(&work_dir, "e", &["a"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a │ ○ d: b │ │ ○ c: b │ ├─╯ │ ○ b: a ├─╯ ○ a ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); let output = work_dir.run_jj(["rebase", "-b", "c", "-o", "e"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 3 commits to destination [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" ○ d: b │ ○ c: b ├─╯ ○ b: e @ e: a ○ a ◆ [EOF] "); // Test rebasing multiple bookmarks at once work_dir.run_jj(["op", "restore", &setup_opid]).success(); let output = work_dir.run_jj(["rebase", "-b=e", "-b=d", "-d=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits to destination Working copy (@) now at: znkkpsqq bbfb8557 e | e Parent commit (@-) : zsuskuln 123b4d91 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: b │ ○ d: b ├─╯ │ ○ c: b ├─╯ ○ b: a ○ a ◆ [EOF] "); // Same test but with more than one revision per argument work_dir.run_jj(["op", "restore", &setup_opid]).success(); let output = work_dir.run_jj(["rebase", "-b=e|d", "-d=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits to destination Working copy (@) now at: znkkpsqq 1ffd7890 e | e Parent commit (@-) : zsuskuln 123b4d91 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: b │ ○ d: b ├─╯ │ ○ c: b ├─╯ ○ b: a ○ a ◆ [EOF] ");} #[test]fn test_rebase_bookmark_with_merge() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &[]); create_commit(&work_dir, "d", &["c"]); create_commit(&work_dir, "e", &["a", "d"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a d ├─╮ │ ○ d: c │ ○ c │ │ ○ b: a ├───╯ ○ │ a ├─╯ ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); let output = work_dir.run_jj(["rebase", "-b", "d", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 3 commits to destination Working copy (@) now at: znkkpsqq d5360d09 e | e Parent commit (@-) : rlvkpnrz 7d980be7 a | a Parent commit (@-) : vruxwmqv 85a741d7 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a d ├─╮ │ ○ d: c │ ○ c: b │ ○ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["op", "restore", &setup_opid]).success(); let output = work_dir.run_jj(["rebase", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 3 commits to destination Working copy (@) now at: znkkpsqq d3091c0f e | e Parent commit (@-) : rlvkpnrz 7d980be7 a | a Parent commit (@-) : vruxwmqv 485905a3 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a d ├─╮ │ ○ d: c │ ○ c: b │ ○ b: a ├─╯ ○ a ◆ [EOF] ");} #[test]fn test_rebase_single_revision() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &["a"]); create_commit(&work_dir, "d", &["b", "c"]); create_commit(&work_dir, "e", &["d"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: d ○ d: b c ├─╮ │ ○ c: a ○ │ b: a ├─╯ ○ a ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); // Descendants of the rebased commit "c" should be rebased onto parents. First // we test with a non-merge commit. let output = work_dir.run_jj(["rebase", "-r", "c", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 1 commits to destination Rebased 2 descendant commits Working copy (@) now at: znkkpsqq 2baedee4 e | e Parent commit (@-) : vruxwmqv 45142a83 d | d Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: d ○ d: b a ├─╮ │ │ ○ c: b ├───╯ ○ │ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["op", "restore", &setup_opid]).success(); // Now, let's try moving the merge commit. After, both parents of "d" ("b" and // "c") should become parents of "e". let output = work_dir.run_jj(["rebase", "-r", "d", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 1 commits to destination Rebased 1 descendant commits Working copy (@) now at: znkkpsqq b981a2bc e | e Parent commit (@-) : zsuskuln 123b4d91 b | b Parent commit (@-) : royxmykx 991a7501 c | c Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: b c ├─╮ │ ○ c: a ○ │ b: a ├─╯ │ ○ d: a ├─╯ ○ a ◆ [EOF] ");} #[test]fn test_rebase_single_revision_merge_parent() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &[]); create_commit(&work_dir, "c", &["b"]); create_commit(&work_dir, "d", &["a", "c"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ d: a c ├─╮ │ ○ c: b │ ○ b ○ │ a ├─╯ ◆ [EOF] "); // Descendants of the rebased commit should be rebased onto parents, and if // the descendant is a merge commit, it shouldn't forget its other parents. let output = work_dir.run_jj(["rebase", "-r", "c", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 1 commits to destination Rebased 1 descendant commits Working copy (@) now at: vruxwmqv 0bb15a0f d | d Parent commit (@-) : rlvkpnrz 7d980be7 a | a Parent commit (@-) : zsuskuln d18ca3e8 b | b Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ d: a b ├─╮ │ ○ b │ │ ○ c: a ├───╯ ○ │ a ├─╯ ◆ [EOF] ");} #[test]fn test_rebase_multiple_revisions() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &["b"]); create_commit(&work_dir, "d", &["a"]); create_commit(&work_dir, "e", &["d"]); create_commit(&work_dir, "f", &["c", "e"]); create_commit(&work_dir, "g", &["f"]); create_commit(&work_dir, "h", &["g"]); create_commit(&work_dir, "i", &["f"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ i: f │ ○ h: g │ ○ g: f ├─╯ ○ f: c e ├─╮ │ ○ e: d │ ○ d: a ○ │ c: b ○ │ b: a ├─╯ ○ a ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); // Test with two non-related non-merge commits. let output = work_dir.run_jj(["rebase", "-r", "c", "-r", "e", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 2 commits to destination Rebased 4 descendant commits Working copy (@) now at: xznxytkn 15078fab i | i Parent commit (@-) : kmkuslsw d8579ed7 f | f Added 0 files, modified 0 files, removed 2 filesLines 1–500 of 3090. Load more
// 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 crate::common::CommandOutput; use crate::common::TestEnvironment; use crate::common::TestWorkDir; use crate::common::create_commit; use crate::common::create_commit_with_files; #[test] fn test_rebase_invalid() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); // Missing destination let output = work_dir.run_jj(["rebase"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the following required arguments were not provided: <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> Usage: jj rebase <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -r and -s let output = work_dir.run_jj(["rebase", "-r", "a", "-s", "a", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--revisions <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -b and -s let output = work_dir.run_jj(["rebase", "-b", "a", "-s", "a", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--branch <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --branch <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -o and --after let output = work_dir.run_jj(["rebase", "-r", "a", "-o", "b", "--after", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--onto <REVSETS>' cannot be used with '--insert-after <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -o and --before let output = work_dir.run_jj(["rebase", "-r", "a", "-o", "b", "--before", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- error: the argument '--onto <REVSETS>' cannot be used with '--insert-before <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--onto <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Rebase onto self with -r let output = work_dir.run_jj(["rebase", "-r", "a", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: Cannot rebase 7d980be7a1d4 onto itself [EOF] [exit status: 1] "); // Rebase root with -r let output = work_dir.run_jj(["rebase", "-r", "root()", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: The root commit 000000000000 is immutable [EOF] [exit status: 1] "); // Rebase onto descendant with -s let output = work_dir.run_jj(["rebase", "-s", "a", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: Cannot rebase 7d980be7a1d4 onto descendant 123b4d91f6e5 [EOF] [exit status: 1] "); // Rebase onto itself with -s let output = work_dir.run_jj(["rebase", "-s", "a", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Error: Cannot rebase 7d980be7a1d4 onto itself [EOF] [exit status: 1] "); } #[test] fn test_rebase_empty_sets() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); let output = work_dir.run_jj(["rebase", "-r=none()", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] "); let output = work_dir.run_jj(["rebase", "-s=none()", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] "); let output = work_dir.run_jj(["rebase", "-b=none()", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] "); // Empty because "b..a" is empty let output = work_dir.run_jj(["rebase", "-b=a", "-o=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- No revisions to rebase. [EOF] "); } #[test] fn test_rebase_bookmark() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &["b"]); create_commit(&work_dir, "d", &["b"]); create_commit(&work_dir, "e", &["a"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a │ ○ d: b │ │ ○ c: b │ ├─╯ │ ○ b: a ├─╯ ○ a ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); let output = work_dir.run_jj(["rebase", "-b", "c", "-o", "e"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 3 commits to destination [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" ○ d: b │ ○ c: b ├─╯ ○ b: e @ e: a ○ a ◆ [EOF] "); // Test rebasing multiple bookmarks at once work_dir.run_jj(["op", "restore", &setup_opid]).success(); let output = work_dir.run_jj(["rebase", "-b=e", "-b=d", "-d=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits to destination Working copy (@) now at: znkkpsqq bbfb8557 e | e Parent commit (@-) : zsuskuln 123b4d91 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: b │ ○ d: b ├─╯ │ ○ c: b ├─╯ ○ b: a ○ a ◆ [EOF] "); // Same test but with more than one revision per argument work_dir.run_jj(["op", "restore", &setup_opid]).success(); let output = work_dir.run_jj(["rebase", "-b=e|d", "-d=b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits to destination Working copy (@) now at: znkkpsqq 1ffd7890 e | e Parent commit (@-) : zsuskuln 123b4d91 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: b │ ○ d: b ├─╯ │ ○ c: b ├─╯ ○ b: a ○ a ◆ [EOF] "); } #[test] fn test_rebase_bookmark_with_merge() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &[]); create_commit(&work_dir, "d", &["c"]); create_commit(&work_dir, "e", &["a", "d"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a d ├─╮ │ ○ d: c │ ○ c │ │ ○ b: a ├───╯ ○ │ a ├─╯ ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); let output = work_dir.run_jj(["rebase", "-b", "d", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 3 commits to destination Working copy (@) now at: znkkpsqq d5360d09 e | e Parent commit (@-) : rlvkpnrz 7d980be7 a | a Parent commit (@-) : vruxwmqv 85a741d7 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a d ├─╮ │ ○ d: c │ ○ c: b │ ○ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["op", "restore", &setup_opid]).success(); let output = work_dir.run_jj(["rebase", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 3 commits to destination Working copy (@) now at: znkkpsqq d3091c0f e | e Parent commit (@-) : rlvkpnrz 7d980be7 a | a Parent commit (@-) : vruxwmqv 485905a3 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: a d ├─╮ │ ○ d: c │ ○ c: b │ ○ b: a ├─╯ ○ a ◆ [EOF] "); } #[test] fn test_rebase_single_revision() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &["a"]); create_commit(&work_dir, "d", &["b", "c"]); create_commit(&work_dir, "e", &["d"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: d ○ d: b c ├─╮ │ ○ c: a ○ │ b: a ├─╯ ○ a ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); // Descendants of the rebased commit "c" should be rebased onto parents. First // we test with a non-merge commit. let output = work_dir.run_jj(["rebase", "-r", "c", "-o", "b"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 1 commits to destination Rebased 2 descendant commits Working copy (@) now at: znkkpsqq 2baedee4 e | e Parent commit (@-) : vruxwmqv 45142a83 d | d Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: d ○ d: b a ├─╮ │ │ ○ c: b ├───╯ ○ │ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["op", "restore", &setup_opid]).success(); // Now, let's try moving the merge commit. After, both parents of "d" ("b" and // "c") should become parents of "e". let output = work_dir.run_jj(["rebase", "-r", "d", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 1 commits to destination Rebased 1 descendant commits Working copy (@) now at: znkkpsqq b981a2bc e | e Parent commit (@-) : zsuskuln 123b4d91 b | b Parent commit (@-) : royxmykx 991a7501 c | c Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ e: b c ├─╮ │ ○ c: a ○ │ b: a ├─╯ │ ○ d: a ├─╯ ○ a ◆ [EOF] "); } #[test] fn test_rebase_single_revision_merge_parent() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &[]); create_commit(&work_dir, "c", &["b"]); create_commit(&work_dir, "d", &["a", "c"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ d: a c ├─╮ │ ○ c: b │ ○ b ○ │ a ├─╯ ◆ [EOF] "); // Descendants of the rebased commit should be rebased onto parents, and if // the descendant is a merge commit, it shouldn't forget its other parents. let output = work_dir.run_jj(["rebase", "-r", "c", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 1 commits to destination Rebased 1 descendant commits Working copy (@) now at: vruxwmqv 0bb15a0f d | d Parent commit (@-) : rlvkpnrz 7d980be7 a | a Parent commit (@-) : zsuskuln d18ca3e8 b | b Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @" @ d: a b ├─╮ │ ○ b │ │ ○ c: a ├───╯ ○ │ a ├─╯ ◆ [EOF] "); } #[test] fn test_rebase_multiple_revisions() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); create_commit(&work_dir, "a", &[]); create_commit(&work_dir, "b", &["a"]); create_commit(&work_dir, "c", &["b"]); create_commit(&work_dir, "d", &["a"]); create_commit(&work_dir, "e", &["d"]); create_commit(&work_dir, "f", &["c", "e"]); create_commit(&work_dir, "g", &["f"]); create_commit(&work_dir, "h", &["g"]); create_commit(&work_dir, "i", &["f"]); // Test the setup insta::assert_snapshot!(get_log_output(&work_dir), @" @ i: f │ ○ h: g │ ○ g: f ├─╯ ○ f: c e ├─╮ │ ○ e: d │ ○ d: a ○ │ c: b ○ │ b: a ├─╯ ○ a ◆ [EOF] "); let setup_opid = work_dir.current_operation_id(); // Test with two non-related non-merge commits. let output = work_dir.run_jj(["rebase", "-r", "c", "-r", "e", "-o", "a"]); insta::assert_snapshot!(output, @" ------- stderr ------- Rebased 2 commits to destination Rebased 4 descendant commits Working copy (@) now at: xznxytkn 15078fab i | i Parent commit (@-) : kmkuslsw d8579ed7 f | f Added 0 files, modified 0 files, removed 2 files