// 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::create_commit;use crate::common::CommandOutput;use crate::common::TestEnvironment;use crate::common::TestWorkDir; #[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, @r" ------- stderr ------- error: the following required arguments were not provided: <--destination <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> Usage: jj rebase <--destination <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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--revisions <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--destination <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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--branch <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --branch <REVSETS> <--destination <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -d and --after let output = work_dir.run_jj(["rebase", "-r", "a", "-d", "b", "--after", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--destination <REVSETS>' cannot be used with '--insert-after <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--destination <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -d and --before let output = work_dir.run_jj(["rebase", "-r", "a", "-d", "b", "--before", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--destination <REVSETS>' cannot be used with '--insert-before <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--destination <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", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Cannot rebase 2443ea76b0b1 onto itself [EOF] [exit status: 1] "); // Rebase root with -r let output = work_dir.run_jj(["rebase", "-r", "root()", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- 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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Cannot rebase 2443ea76b0b1 onto descendant 1394f625cbbd [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"]); // TODO: Make all of these say "Nothing changed"? let output = work_dir.run_jj(["rebase", "-r=none()", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. [EOF] "); let output = work_dir.run_jj(["rebase", "-s=none()", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Revset `none()` didn't resolve to any revisions [EOF] [exit status: 1] "); let output = work_dir.run_jj(["rebase", "-b=none()", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Revset `none()` didn't resolve to any revisions [EOF] [exit status: 1] "); // Empty because "b..a" is empty let output = work_dir.run_jj(["rebase", "-b=a", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. [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), @r" @ e: a │ ○ d: b │ │ ○ c: b │ ├─╯ │ ○ b: a ├─╯ ○ a ◆ [EOF] "); let output = work_dir.run_jj(["rebase", "-b", "c", "-d", "e"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 3 commits onto destination [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" ○ d: b │ ○ c: b ├─╯ ○ b: e @ e: a ○ a ◆ [EOF] "); // Test rebasing multiple bookmarks at once work_dir.run_jj(["undo"]).success(); let output = work_dir.run_jj(["rebase", "-b=e", "-b=d", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits onto destination Working copy (@) now at: znkkpsqq 9ca2a154 e | e Parent commit (@-) : zsuskuln 1394f625 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ e: b │ ○ d: b ├─╯ │ ○ c: b ├─╯ ○ b: a ○ a ◆ [EOF] "); // Same test but with more than one revision per argument work_dir.run_jj(["undo"]).success(); let output = work_dir.run_jj(["rebase", "-b=e|d", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Revset `e|d` resolved to more than one revision Hint: The revset `e|d` resolved to these revisions: znkkpsqq e52756c8 e | e vruxwmqv 514fa6b2 d | d Hint: Prefix the expression with `all:` to allow any number of revisions (i.e. `all:e|d`). [EOF] [exit status: 1] "); let output = work_dir.run_jj(["rebase", "-b=all:e|d", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits onto destination Working copy (@) now at: znkkpsqq 817e3fb0 e | e Parent commit (@-) : zsuskuln 1394f625 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ e: a d ├─╮ │ ○ d: c │ ○ c │ │ ○ b: a ├───╯ ○ │ a ├─╯ ◆ [EOF] "); let output = work_dir.run_jj(["rebase", "-b", "d", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 3 commits onto destination Working copy (@) now at: znkkpsqq 5f8a3db2 e | e Parent commit (@-) : rlvkpnrz 2443ea76 a | a Parent commit (@-) : vruxwmqv 1677f795 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ e: a d ├─╮ │ ○ d: c │ ○ c: b │ ○ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["undo"]).success(); let output = work_dir.run_jj(["rebase", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 3 commits onto destination Working copy (@) now at: znkkpsqq a331ac11 e | e Parent commit (@-) : rlvkpnrz 2443ea76 a | a Parent commit (@-) : vruxwmqv 3d0f3644 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ e: d ○ d: b c ├─╮ │ ○ c: a ○ │ b: a ├─╯ ○ a ◆ [EOF] "); // 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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits onto destination Rebased 2 descendant commits Working copy (@) now at: znkkpsqq 2668ffbe e | e Parent commit (@-) : vruxwmqv 7b370c85 d | d Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ e: d ○ d: b a ├─╮ │ │ ○ c: b ├───╯ ○ │ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["undo"]).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", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits onto destination Rebased 1 descendant commits Working copy (@) now at: znkkpsqq ed210c15 e | e Parent commit (@-) : zsuskuln 1394f625 b | b Parent commit (@-) : royxmykx c0cb3a0b c | c Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ 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", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits onto destination Rebased 1 descendant commits Working copy (@) now at: vruxwmqv a37531e8 d | d Parent commit (@-) : rlvkpnrz 2443ea76 a | a Parent commit (@-) : zsuskuln d370aee1 b | b Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ i: f │ ○ h: g │ ○ g: f ├─╯ ○ f: c e ├─╮ │ ○ e: d │ ○ d: a ○ │ c: b ○ │ b: a ├─╯ ○ a ◆ [EOF] "); // Test with two non-related non-merge commits. let output = work_dir.run_jj(["rebase", "-r", "c", "-r", "e", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 2 commits onto destination Rebased 4 descendant commits Working copy (@) now at: xznxytkn 016685dc i | i Parent commit (@-) : kmkuslsw e04d3932 f | f Added 0 files, modified 0 files, removed 2 filesLines 1–500 of 2982. 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::create_commit; use crate::common::CommandOutput; use crate::common::TestEnvironment; use crate::common::TestWorkDir; #[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, @r" ------- stderr ------- error: the following required arguments were not provided: <--destination <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> Usage: jj rebase <--destination <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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--revisions <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--destination <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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--branch <REVSETS>' cannot be used with '--source <REVSETS>' Usage: jj rebase --branch <REVSETS> <--destination <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -d and --after let output = work_dir.run_jj(["rebase", "-r", "a", "-d", "b", "--after", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--destination <REVSETS>' cannot be used with '--insert-after <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--destination <REVSETS>|--insert-after <REVSETS>|--insert-before <REVSETS>> For more information, try '--help'. [EOF] [exit status: 2] "); // Both -d and --before let output = work_dir.run_jj(["rebase", "-r", "a", "-d", "b", "--before", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the argument '--destination <REVSETS>' cannot be used with '--insert-before <REVSETS>' Usage: jj rebase --revisions <REVSETS> <--destination <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", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Cannot rebase 2443ea76b0b1 onto itself [EOF] [exit status: 1] "); // Rebase root with -r let output = work_dir.run_jj(["rebase", "-r", "root()", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- 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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Cannot rebase 2443ea76b0b1 onto descendant 1394f625cbbd [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"]); // TODO: Make all of these say "Nothing changed"? let output = work_dir.run_jj(["rebase", "-r=none()", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. [EOF] "); let output = work_dir.run_jj(["rebase", "-s=none()", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Revset `none()` didn't resolve to any revisions [EOF] [exit status: 1] "); let output = work_dir.run_jj(["rebase", "-b=none()", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Revset `none()` didn't resolve to any revisions [EOF] [exit status: 1] "); // Empty because "b..a" is empty let output = work_dir.run_jj(["rebase", "-b=a", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. [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), @r" @ e: a │ ○ d: b │ │ ○ c: b │ ├─╯ │ ○ b: a ├─╯ ○ a ◆ [EOF] "); let output = work_dir.run_jj(["rebase", "-b", "c", "-d", "e"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 3 commits onto destination [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" ○ d: b │ ○ c: b ├─╯ ○ b: e @ e: a ○ a ◆ [EOF] "); // Test rebasing multiple bookmarks at once work_dir.run_jj(["undo"]).success(); let output = work_dir.run_jj(["rebase", "-b=e", "-b=d", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits onto destination Working copy (@) now at: znkkpsqq 9ca2a154 e | e Parent commit (@-) : zsuskuln 1394f625 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ e: b │ ○ d: b ├─╯ │ ○ c: b ├─╯ ○ b: a ○ a ◆ [EOF] "); // Same test but with more than one revision per argument work_dir.run_jj(["undo"]).success(); let output = work_dir.run_jj(["rebase", "-b=e|d", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Revset `e|d` resolved to more than one revision Hint: The revset `e|d` resolved to these revisions: znkkpsqq e52756c8 e | e vruxwmqv 514fa6b2 d | d Hint: Prefix the expression with `all:` to allow any number of revisions (i.e. `all:e|d`). [EOF] [exit status: 1] "); let output = work_dir.run_jj(["rebase", "-b=all:e|d", "-d=b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Skipped rebase of 1 commits that were already in place Rebased 1 commits onto destination Working copy (@) now at: znkkpsqq 817e3fb0 e | e Parent commit (@-) : zsuskuln 1394f625 b | b Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ e: a d ├─╮ │ ○ d: c │ ○ c │ │ ○ b: a ├───╯ ○ │ a ├─╯ ◆ [EOF] "); let output = work_dir.run_jj(["rebase", "-b", "d", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 3 commits onto destination Working copy (@) now at: znkkpsqq 5f8a3db2 e | e Parent commit (@-) : rlvkpnrz 2443ea76 a | a Parent commit (@-) : vruxwmqv 1677f795 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ e: a d ├─╮ │ ○ d: c │ ○ c: b │ ○ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["undo"]).success(); let output = work_dir.run_jj(["rebase", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 3 commits onto destination Working copy (@) now at: znkkpsqq a331ac11 e | e Parent commit (@-) : rlvkpnrz 2443ea76 a | a Parent commit (@-) : vruxwmqv 3d0f3644 d | d Added 1 files, modified 0 files, removed 0 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ e: d ○ d: b c ├─╮ │ ○ c: a ○ │ b: a ├─╯ ○ a ◆ [EOF] "); // 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", "-d", "b"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits onto destination Rebased 2 descendant commits Working copy (@) now at: znkkpsqq 2668ffbe e | e Parent commit (@-) : vruxwmqv 7b370c85 d | d Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ e: d ○ d: b a ├─╮ │ │ ○ c: b ├───╯ ○ │ b: a ├─╯ ○ a ◆ [EOF] "); work_dir.run_jj(["undo"]).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", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits onto destination Rebased 1 descendant commits Working copy (@) now at: znkkpsqq ed210c15 e | e Parent commit (@-) : zsuskuln 1394f625 b | b Parent commit (@-) : royxmykx c0cb3a0b c | c Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ 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", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits onto destination Rebased 1 descendant commits Working copy (@) now at: vruxwmqv a37531e8 d | d Parent commit (@-) : rlvkpnrz 2443ea76 a | a Parent commit (@-) : zsuskuln d370aee1 b | b Added 0 files, modified 0 files, removed 1 files [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 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), @r" @ i: f │ ○ h: g │ ○ g: f ├─╯ ○ f: c e ├─╮ │ ○ e: d │ ○ d: a ○ │ c: b ○ │ b: a ├─╯ ○ a ◆ [EOF] "); // Test with two non-related non-merge commits. let output = work_dir.run_jj(["rebase", "-r", "c", "-r", "e", "-d", "a"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 2 commits onto destination Rebased 4 descendant commits Working copy (@) now at: xznxytkn 016685dc i | i Parent commit (@-) : kmkuslsw e04d3932 f | f Added 0 files, modified 0 files, removed 2 files