594 lines · 19.4 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::CommandOutput;use crate::common::TestEnvironment;use crate::common::TestWorkDir;use crate::common::create_commit_with_files; #[test]fn test_restore() {    let test_env = TestEnvironment::default();    test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");     work_dir.write_file("file1", "a\n");    work_dir.run_jj(["new"]).success();    work_dir.write_file("file2", "b\n");    work_dir.run_jj(["new"]).success();    work_dir.remove_file("file1");    work_dir.write_file("file2", "c\n");    work_dir.write_file("file3", "c\n");    work_dir.run_jj(["debug", "snapshot"]).success();    let setup_opid = work_dir.current_operation_id();     // There is no `-r` argument    let output = work_dir.run_jj(["restore", "-r=@-"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Error: `jj restore` does not have a `--revision`/`-r` option.    Hint: To modify the current revision, use `--from`.    Hint: To undo changes in a revision compared to its parents, use `--changes-in`.    [EOF]    [exit status: 1]    ");     // Restores from parent by default    let output = work_dir.run_jj(["restore"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: kkmpptxz ff7ef1df (empty) (no description set)    Parent commit (@-)      : rlvkpnrz 1d3e40a3 (no description set)    Added 1 files, modified 1 files, removed 1 files    [EOF]    ");    let output = work_dir.run_jj(["diff", "-s"]);    insta::assert_snapshot!(output, @"");     // Can restore another revision from its parents    work_dir.run_jj(["op", "restore", &setup_opid]).success();    let output = work_dir.run_jj(["diff", "-s", "-r=@-"]);    insta::assert_snapshot!(output, @"    A file2    [EOF]    ");    let output = work_dir.run_jj(["restore", "-c=@-"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Rebased 1 descendant commits    Working copy  (@) now at: kkmpptxz faa5911c (conflict) (no description set)    Parent commit (@-)      : rlvkpnrz 67841e01 (empty) (no description set)    Added 0 files, modified 1 files, removed 0 files    Warning: There are unresolved conflicts at these paths:    file2    2-sided conflict including 1 deletion    New conflicts appeared in 1 commits:      kkmpptxz faa5911c (conflict) (no description set)    Hint: To resolve the conflicts, start by creating a commit on top of    the conflicted commit:      jj new kkmpptxz    Then use `jj resolve`, or edit the conflict markers in the file directly.    Once the conflicts are resolved, you can inspect the result with `jj diff`.    Then run `jj squash` to move the resolution into the conflicted commit.    [EOF]    ");    let output = work_dir.run_jj(["diff", "-s", "-r=@-"]);    insta::assert_snapshot!(output, @"");     // Can restore this revision from another revision    work_dir.run_jj(["op", "restore", &setup_opid]).success();    let output = work_dir.run_jj(["restore", "--from", "@--"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: kkmpptxz 3beda426 (no description set)    Parent commit (@-)      : rlvkpnrz 1d3e40a3 (no description set)    Added 1 files, modified 0 files, removed 2 files    [EOF]    ");    let output = work_dir.run_jj(["diff", "-s"]);    insta::assert_snapshot!(output, @"    D file2    [EOF]    ");     // Can restore into other revision    work_dir.run_jj(["op", "restore", &setup_opid]).success();    let output = work_dir.run_jj(["restore", "--into", "@-"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Rebased 1 descendant commits    Working copy  (@) now at: kkmpptxz 5edd8125 (empty) (no description set)    Parent commit (@-)      : rlvkpnrz e01fe0b9 (no description set)    [EOF]    ");    let output = work_dir.run_jj(["diff", "-s"]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["diff", "-s", "-r", "@-"]);    insta::assert_snapshot!(output, @"    D file1    A file2    A file3    [EOF]    ");     // Can combine `--from` and `--into`    work_dir.run_jj(["op", "restore", &setup_opid]).success();    let output = work_dir.run_jj(["restore", "--from", "@", "--into", "@-"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Rebased 1 descendant commits    Working copy  (@) now at: kkmpptxz 9807d79b (empty) (no description set)    Parent commit (@-)      : rlvkpnrz f3774db8 (no description set)    [EOF]    ");    let output = work_dir.run_jj(["diff", "-s"]);    insta::assert_snapshot!(output, @"");    let output = work_dir.run_jj(["diff", "-s", "-r", "@-"]);    insta::assert_snapshot!(output, @"    D file1    A file2    A file3    [EOF]    ");     // Can restore only specified paths    work_dir.run_jj(["op", "restore", &setup_opid]).success();    let output = work_dir.run_jj(["restore", "file2", "file3"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: kkmpptxz 08b04134 (no description set)    Parent commit (@-)      : rlvkpnrz 1d3e40a3 (no description set)    Added 0 files, modified 1 files, removed 1 files    [EOF]    ");    let output = work_dir.run_jj(["diff", "-s"]);    insta::assert_snapshot!(output, @"    D file1    [EOF]    ");     // The output filtered to a non-existent file should display a warning.    let output = work_dir.run_jj(["restore", "nonexistent"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Warning: No matching entries for paths: nonexistent    Nothing changed.    [EOF]    ");} // Much of this test is copied from test_resolve_command#[test]fn test_restore_conflicted_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_with_files(&work_dir, "base", &[], &[("file", "base\n")]);    create_commit_with_files(&work_dir, "a", &["base"], &[("file", "a\n")]);    create_commit_with_files(&work_dir, "b", &["base"], &[("file", "b\n")]);    create_commit_with_files(&work_dir, "conflict", &["a", "b"], &[]);    // Test the setup    insta::assert_snapshot!(get_log_output(&work_dir), @"    @    conflict    ├─╮    │ ○  b    ○ │  a    ├─╯    ○  base    ◆    [EOF]    ");    insta::assert_snapshot!(work_dir.read_file("file"), @r#"    <<<<<<< conflict 1 of 1    %%%%%%% diff from: rlvkpnrz 1792382a "base"    \\\\\\\        to: zsuskuln 45537d53 "a"    -base    +a    +++++++ royxmykx 89d1b299 "b"    b    >>>>>>> conflict 1 of 1 ends    "#);     // Overwrite the file...    work_dir.write_file("file", "resolution");    insta::assert_snapshot!(work_dir.run_jj(["diff"]), @r#"    Resolved conflict in file:       1     : <<<<<<< conflict 1 of 1       2     : %%%%%%% diff from: rlvkpnrz 1792382a "base"       3     : \\\\\\\        to: zsuskuln 45537d53 "a"       4     : -base       5     : +a       6     : +++++++ royxmykx 89d1b299 "b"       7     : b       8     : >>>>>>> conflict 1 of 1 ends            1: resolution    [EOF]    "#);     // ...and restore it back again.    let output = work_dir.run_jj(["restore", "file"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: vruxwmqv 7efcd5f8 conflict | (conflict) (empty) conflict    Parent commit (@-)      : zsuskuln 45537d53 a | a    Parent commit (@-)      : royxmykx 89d1b299 b | b    Added 0 files, modified 1 files, removed 0 files    Warning: There are unresolved conflicts at these paths:    file    2-sided conflict    [EOF]    ");    insta::assert_snapshot!(work_dir.read_file("file"), @r#"    <<<<<<< conflict 1 of 1    %%%%%%% diff from: rlvkpnrz 1792382a "base"    \\\\\\\        to: zsuskuln 45537d53 "a"    -base    +a    +++++++ royxmykx 89d1b299 "b"    b    >>>>>>> conflict 1 of 1 ends    "#);    let output = work_dir.run_jj(["diff"]);    insta::assert_snapshot!(output, @"");     // The same, but without the `file` argument. Overwrite the file...    work_dir.write_file("file", "resolution");    insta::assert_snapshot!(work_dir.run_jj(["diff"]), @r#"    Resolved conflict in file:       1     : <<<<<<< conflict 1 of 1       2     : %%%%%%% diff from: rlvkpnrz 1792382a "base"       3     : \\\\\\\        to: zsuskuln 45537d53 "a"       4     : -base       5     : +a       6     : +++++++ royxmykx 89d1b299 "b"       7     : b       8     : >>>>>>> conflict 1 of 1 ends            1: resolution    [EOF]    "#);     // ... and restore it back again.    let output = work_dir.run_jj(["restore"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: vruxwmqv e0c3b307 conflict | (conflict) (empty) conflict    Parent commit (@-)      : zsuskuln 45537d53 a | a    Parent commit (@-)      : royxmykx 89d1b299 b | b    Added 0 files, modified 1 files, removed 0 files    Warning: There are unresolved conflicts at these paths:    file    2-sided conflict    [EOF]    ");    insta::assert_snapshot!(work_dir.read_file("file"), @r#"    <<<<<<< conflict 1 of 1    %%%%%%% diff from: rlvkpnrz 1792382a "base"    \\\\\\\        to: zsuskuln 45537d53 "a"    -base    +a    +++++++ royxmykx 89d1b299 "b"    b    >>>>>>> conflict 1 of 1 ends    "#);} #[test]fn test_restore_restore_descendants() {    let test_env = TestEnvironment::default();    test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");     create_commit_with_files(&work_dir, "base", &[], &[("file", "base\n")]);    create_commit_with_files(&work_dir, "a", &["base"], &[("file", "a\n")]);    create_commit_with_files(        &work_dir,        "b",        &["base"],        &[("file", "b\n"), ("file2", "b\n")],    );    create_commit_with_files(&work_dir, "ab", &["a", "b"], &[("file", "ab\n")]);    // Test the setup    insta::assert_snapshot!(get_log_output(&work_dir), @"    @    ab    ├─╮    │ ○  b    ○ │  a    ├─╯    ○  base    ◆    [EOF]    ");    insta::assert_snapshot!(work_dir.read_file("file"), @"ab");     // Commit "b" was not supposed to modify "file", restore it from its parent    // while preserving its child commit content.    let output = work_dir.run_jj(["restore", "-c", "b", "file", "--restore-descendants"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Rebased 1 descendant commits (while preserving their content)    Working copy  (@) now at: vruxwmqv 14c0c336 ab | ab    Parent commit (@-)      : zsuskuln 45537d53 a | a    Parent commit (@-)      : royxmykx 5fd3f8c5 b | b    [EOF]    ");     // Check that "a", "b", and "ab" have their expected content by diffing them.    // "ab" must have kept its content.    insta::assert_snapshot!(work_dir.run_jj(["diff", "--from=a", "--to=ab", "--git"]), @"    diff --git a/file b/file    index 7898192261..81bf396956 100644    --- a/file    +++ b/file    @@ -1,1 +1,1 @@    -a    +ab    diff --git a/file2 b/file2    new file mode 100644    index 0000000000..6178079822    --- /dev/null    +++ b/file2    @@ -0,0 +1,1 @@    +b    [EOF]    ");    insta::assert_snapshot!(work_dir.run_jj(["diff", "--from=b", "--to=ab", "--git"]), @"    diff --git a/file b/file    index df967b96a5..81bf396956 100644    --- a/file    +++ b/file    @@ -1,1 +1,1 @@    -base    +ab    [EOF]    ");} #[test]fn test_restore_interactive() {    let mut test_env = TestEnvironment::default();    let diff_editor = test_env.set_up_fake_diff_editor();    test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");     create_commit_with_files(&work_dir, "a", &[], &[("file1", "a1\n"), ("file2", "a2\n")]);    create_commit_with_files(        &work_dir,        "b",        &["a"],        &[("file1", "b1\n"), ("file2", "b2\n"), ("file3", "b3\n")],    );    let output = work_dir.run_jj(["log", "--summary"]);    insta::assert_snapshot!(output, @"    @  zsuskuln test.user@example.com 2001-02-03 08:05:11 b 38153274    │  b    │  M file1    │  M file2    │  A file3    ○  rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 6c8d5b87    │  a    │  A file1    │  A file2    ◆  zzzzzzzz root() 00000000    [EOF]    ");    let setup_opid = work_dir.current_operation_id();     let diff_script = [        "files-before file1 file2 file3",        "files-after JJ-INSTRUCTIONS file1 file2",        "reset file2",        "dump JJ-INSTRUCTIONS instrs",    ]    .join("\0");    std::fs::write(diff_editor, diff_script).unwrap();     // Restore file1 and file3    let output = work_dir.run_jj(["restore", "-i", "--from=@-"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: zsuskuln 7cd0a341 b | b    Parent commit (@-)      : rlvkpnrz 6c8d5b87 a | a    Added 0 files, modified 1 files, removed 1 files    [EOF]    ");     insta::assert_snapshot!(        std::fs::read_to_string(test_env.env_root().join("instrs")).unwrap(), @"    You are restoring changes from: rlvkpnrz 6c8d5b87 a | a    to commit: zsuskuln 38153274 b | b     The diff initially shows all changes restored. Adjust the right side until it    shows the contents you want for the destination commit.    ");     let output = work_dir.run_jj(["log", "--summary"]);    insta::assert_snapshot!(output, @"    @  zsuskuln test.user@example.com 2001-02-03 08:05:13 b 7cd0a341    │  b    │  M file2    ○  rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 6c8d5b87    │  a    │  A file1    │  A file2    ◆  zzzzzzzz root() 00000000    [EOF]    ");     // Try again with --tool, which should imply --interactive    work_dir.run_jj(["op", "restore", &setup_opid]).success();    let output = work_dir.run_jj(["restore", "--tool=fake-diff-editor"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: zsuskuln 0f1263f5 b | b    Parent commit (@-)      : rlvkpnrz 6c8d5b87 a | a    Added 0 files, modified 1 files, removed 1 files    [EOF]    ");     let output = work_dir.run_jj(["log", "--summary"]);    insta::assert_snapshot!(output, @"    @  zsuskuln test.user@example.com 2001-02-03 08:05:16 b 0f1263f5    │  b    │  M file2    ○  rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 6c8d5b87    │  a    │  A file1    │  A file2    ◆  zzzzzzzz root() 00000000    [EOF]    ");} #[test]fn test_restore_interactive_merge() {    let mut test_env = TestEnvironment::default();    let diff_editor = test_env.set_up_fake_diff_editor();    test_env.run_jj_in(".", ["git", "init", "repo"]).success();    let work_dir = test_env.work_dir("repo");     create_commit_with_files(&work_dir, "a", &[], &[("file1", "a1\n")]);    create_commit_with_files(&work_dir, "b", &[], &[("file2", "b1\n")]);    create_commit_with_files(        &work_dir,        "c",        &["a", "b"],        &[("file1", "c1\n"), ("file2", "c2\n"), ("file3", "c3\n")],    );    let output = work_dir.run_jj(["log", "--summary"]);    insta::assert_snapshot!(output, @"    @    royxmykx test.user@example.com 2001-02-03 08:05:13 c e37470c3    ├─╮  c    │ │  M file1    │ │  M file2    │ │  A file3    │ ○  zsuskuln test.user@example.com 2001-02-03 08:05:11 b ca7e57cd    │ │  b    │ │  A file2    ○ │  rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 78059355    ├─╯  a    │    A file1    ◆  zzzzzzzz root() 00000000    [EOF]    ");     let diff_script = [        "files-before file1 file2 file3",        "files-after JJ-INSTRUCTIONS file1 file2",        "reset file2",        "dump JJ-INSTRUCTIONS instrs",    ]    .join("\0");    std::fs::write(diff_editor, diff_script).unwrap();     // Restore file1 and file3    let output = work_dir.run_jj(["restore", "-i"]);    insta::assert_snapshot!(output, @"    ------- stderr -------    Working copy  (@) now at: royxmykx 196af27b c | c    Parent commit (@-)      : rlvkpnrz 78059355 a | a    Parent commit (@-)      : zsuskuln ca7e57cd b | b    Added 0 files, modified 1 files, removed 1 files    [EOF]

Lines 1–500 of 594.