2982 lines · 84.7 KB · Rust
RawDownload
// 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

Lines 1–500 of 2982.