// Copyright 2024 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 testutils::TestResult; use crate::common::CommandOutput;use crate::common::TestEnvironment;use crate::common::TestWorkDir; #[test]fn test_absorb_simple() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m0"]).success(); work_dir.write_file("file1", ""); work_dir.run_jj(["new", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n"); work_dir.run_jj(["new", "-m2"]).success(); work_dir.write_file("file1", "1a\n1b\n2a\n2b\n"); // Empty commit work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Nothing changed. [EOF] "); // Insert first and last lines work_dir.write_file("file1", "1X\n1a\n1b\n2a\n2b\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Absorbed changes into 2 revisions: zsuskuln 95568809 2 kkmpptxz bd7d4016 1 Working copy (@) now at: yqosqzyt 977269ac (empty) (no description set) Parent commit (@-) : zsuskuln 95568809 2 [EOF] "); // Modify middle line in hunk work_dir.write_file("file1", "1X\n1A\n1b\n2a\n2b\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 1 revisions: kkmpptxz 5810eb0f 1 Rebased 1 descendant commits. Working copy (@) now at: vruxwmqv 48c7d8fa (empty) (no description set) Parent commit (@-) : zsuskuln 8edd60a2 2 [EOF] "); // Remove middle line from hunk work_dir.write_file("file1", "1X\n1A\n1b\n2a\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Absorbed changes into 1 revisions: zsuskuln dd109863 2 Working copy (@) now at: yostqsxw 7482f74b (empty) (no description set) Parent commit (@-) : zsuskuln dd109863 2 [EOF] "); // Insert ambiguous line in between work_dir.write_file("file1", "1X\n1A\n1b\nY\n2a\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Nothing changed. [EOF] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @" @ yostqsxw bde51bc9 (no description set) │ diff --git a/file1 b/file1 │ index 8653ca354d..88eb438902 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,5 +1,6 @@ │ 1X │ 1A │ 1b │ +Y │ 2a │ 2Z ○ zsuskuln dd109863 2 │ diff --git a/file1 b/file1 │ index ed237b5112..8653ca354d 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,3 +1,5 @@ │ 1X │ 1A │ 1b │ +2a │ +2Z ○ kkmpptxz 5810eb0f 1 │ diff --git a/file1 b/file1 │ index e69de29bb2..ed237b5112 100644 │ --- a/file1 │ +++ b/file1 │ @@ -0,0 +1,3 @@ │ +1X │ +1A │ +1b ○ qpvuntsm 6a446874 0 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..e69de29bb2 [EOF] "); insta::assert_snapshot!(get_evolog(&work_dir, "subject(1)"), @" ○ kkmpptxz 5810eb0f 1 ├─╮ │ ○ yqosqzyt/0 39b42898 (hidden) (no description set) │ ○ yqosqzyt/1 977269ac (hidden) (empty) (no description set) ○ kkmpptxz/1 bd7d4016 (hidden) 1 ├─╮ │ ○ mzvwutvl/0 0b307741 (hidden) (no description set) │ ○ mzvwutvl/1 f2709b4e (hidden) (empty) (no description set) ○ kkmpptxz/2 1553c5e8 (hidden) 1 ○ kkmpptxz/3 eb943711 (hidden) (empty) 1 [EOF] "); insta::assert_snapshot!(get_evolog(&work_dir, "subject(2)"), @" ○ zsuskuln dd109863 2 ├─╮ │ ○ vruxwmqv/0 761492a8 (hidden) (no description set) │ ○ vruxwmqv/1 48c7d8fa (hidden) (empty) (no description set) ○ zsuskuln/1 8edd60a2 (hidden) 2 ○ zsuskuln/2 95568809 (hidden) 2 ├─╮ │ ○ mzvwutvl/0 0b307741 (hidden) (no description set) │ ○ mzvwutvl/1 f2709b4e (hidden) (empty) (no description set) ○ zsuskuln/3 36fad385 (hidden) 2 ○ zsuskuln/4 561fbce9 (hidden) (empty) 2 [EOF] ");} #[test]fn test_absorb_replace_single_line_hunk() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m1"]).success(); work_dir.write_file("file1", "1a\n"); work_dir.run_jj(["new", "-m2"]).success(); work_dir.write_file("file1", "2a\n1a\n2b\n"); // Replace single-line hunk, which produces a conflict right now. If our // merge logic were based on interleaved delta, the hunk would be applied // cleanly. work_dir.run_jj(["new"]).success(); work_dir.write_file("file1", "2a\n1A\n2b\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 1 revisions: qpvuntsm 125fba68 (conflict) 1 Rebased 1 descendant commits. Working copy (@) now at: mzvwutvl deeb043a (empty) (no description set) Parent commit (@-) : kkmpptxz 732472fb 2 New conflicts appeared in 1 commits: qpvuntsm 125fba68 (conflict) 1 Hint: To resolve the conflicts, start by creating a commit on top of the conflicted commit: jj new qpvuntsm 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] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r#" @ mzvwutvl deeb043a (empty) (no description set) ○ kkmpptxz 732472fb 2 │ diff --git a/file1 b/file1 │ index 0000000000..2f87e8e465 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,11 +1,3 @@ │ -<<<<<<< conflict 1 of 1 │ -%%%%%%% diff from: kkmpptxz 9d700628 "2" (parents of absorbed revision) │ -\\\\\\\ to: qpvuntsm aa6cb9bc "1" (absorb destination) │ --2a │ - 1a │ --2b │ -+++++++ absorbed changes (from zsuskuln 5d926f12) │ 2a │ 1A │ 2b │ ->>>>>>> conflict 1 of 1 ends × qpvuntsm 125fba68 (conflict) 1 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..0000000000 --- /dev/null +++ b/file1 @@ -0,0 +1,11 @@ +<<<<<<< conflict 1 of 1 +%%%%%%% diff from: kkmpptxz 9d700628 "2" (parents of absorbed revision) +\\\\\\\ to: qpvuntsm aa6cb9bc "1" (absorb destination) +-2a + 1a +-2b ++++++++ absorbed changes (from zsuskuln 5d926f12) +2a +1A +2b +>>>>>>> conflict 1 of 1 ends [EOF] "#);} #[test]fn test_absorb_merge() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m0"]).success(); work_dir.write_file("file1", "0a\n"); work_dir.run_jj(["new", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n0a\n"); work_dir.run_jj(["new", "-m2", "subject(0)"]).success(); work_dir.write_file("file1", "0a\n2a\n2b\n"); let output = work_dir.run_jj(["new", "-m3", "subject(1)", "subject(2)"]); insta::assert_snapshot!(output, @" ------- stderr ------- Working copy (@) now at: mzvwutvl 42875bf7 (empty) 3 Parent commit (@-) : kkmpptxz 9c66f62f 1 Parent commit (@-) : zsuskuln 6a3dcbcf 2 Added 0 files, modified 1 files, removed 0 files [EOF] "); // Modify first and last lines, absorb from merge work_dir.write_file("file1", "1A\n1b\n0a\n2a\n2B\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 2 revisions: zsuskuln a6fde7ea 2 kkmpptxz 00ecc958 1 Rebased 1 descendant commits. Working copy (@) now at: mzvwutvl 30499858 (empty) 3 Parent commit (@-) : kkmpptxz 00ecc958 1 Parent commit (@-) : zsuskuln a6fde7ea 2 [EOF] "); // Add hunk to merge revision work_dir.write_file("file2", "3a\n"); // Absorb into merge work_dir.run_jj(["new"]).success(); work_dir.write_file("file2", "3A\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Absorbed changes into 1 revisions: mzvwutvl faf778a4 3 Working copy (@) now at: vruxwmqv cec519a1 (empty) (no description set) Parent commit (@-) : mzvwutvl faf778a4 3 [EOF] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @" @ vruxwmqv cec519a1 (empty) (no description set) ○ mzvwutvl faf778a4 3 ├─╮ diff --git a/file2 b/file2 │ │ new file mode 100644 │ │ index 0000000000..44442d2d7b │ │ --- /dev/null │ │ +++ b/file2 │ │ @@ -0,0 +1,1 @@ │ │ +3A │ ○ zsuskuln a6fde7ea 2 │ │ diff --git a/file1 b/file1 │ │ index eb6e8821f1..4907935b9f 100644 │ │ --- a/file1 │ │ +++ b/file1 │ │ @@ -1,1 +1,3 @@ │ │ 0a │ │ +2a │ │ +2B ○ │ kkmpptxz 00ecc958 1 ├─╯ diff --git a/file1 b/file1 │ index eb6e8821f1..902dd8ef13 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,1 +1,3 @@ │ +1A │ +1b │ 0a ○ qpvuntsm d4f07be5 0 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..eb6e8821f1 --- /dev/null +++ b/file1 @@ -0,0 +1,1 @@ +0a [EOF] ");} #[test]fn test_absorb_discardable_merge_with_descendant() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m0"]).success(); work_dir.write_file("file1", "0a\n"); work_dir.run_jj(["new", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n0a\n"); work_dir.run_jj(["new", "-m2", "subject(0)"]).success(); work_dir.write_file("file1", "0a\n2a\n2b\n"); let output = work_dir.run_jj(["new", "subject(1)", "subject(2)"]); insta::assert_snapshot!(output, @" ------- stderr ------- Working copy (@) now at: mzvwutvl ad00b91a (empty) (no description set) Parent commit (@-) : kkmpptxz 9c66f62f 1 Parent commit (@-) : zsuskuln 6a3dcbcf 2 Added 0 files, modified 1 files, removed 0 files [EOF] "); // Modify first and last lines in the merge commit work_dir.write_file("file1", "1A\n1b\n0a\n2a\n2B\n"); // Add new commit on top work_dir.run_jj(["new", "-m3"]).success(); work_dir.write_file("file2", "3a\n"); // Then absorb the merge commit let output = work_dir.run_jj(["absorb", "--from=@-"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 2 revisions: zsuskuln a6cd8e87 2 kkmpptxz 98b7d214 1 Rebased 1 descendant commits. Working copy (@) now at: royxmykx df946e9b 3 Parent commit (@-) : kkmpptxz 98b7d214 1 Parent commit (@-) : zsuskuln a6cd8e87 2 [EOF] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @" @ royxmykx df946e9b 3 ├─╮ diff --git a/file2 b/file2 │ │ new file mode 100644 │ │ index 0000000000..31cd755d20 │ │ --- /dev/null │ │ +++ b/file2 │ │ @@ -0,0 +1,1 @@ │ │ +3a │ ○ zsuskuln a6cd8e87 2 │ │ diff --git a/file1 b/file1 │ │ index eb6e8821f1..4907935b9f 100644 │ │ --- a/file1 │ │ +++ b/file1 │ │ @@ -1,1 +1,3 @@ │ │ 0a │ │ +2a │ │ +2B ○ │ kkmpptxz 98b7d214 1 ├─╯ diff --git a/file1 b/file1 │ index eb6e8821f1..902dd8ef13 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,1 +1,3 @@ │ +1A │ +1b │ 0a ○ qpvuntsm d4f07be5 0 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..eb6e8821f1 --- /dev/null +++ b/file1 @@ -0,0 +1,1 @@ +0a [EOF] ");} #[test]fn test_absorb_conflict() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n"); work_dir.run_jj(["new", "root()"]).success(); work_dir.write_file("file1", "2a\n2b\n"); let output = work_dir.run_jj(["rebase", "-r@", "-dsubject(1)"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits to destination. Working copy (@) now at: kkmpptxz 628e2b00 (conflict) (no description set) Parent commit (@-) : qpvuntsm e35bcaff 1 Added 0 files, modified 1 files, removed 0 files Warning: There are unresolved conflicts at these paths: file1 2-sided conflict New conflicts appeared in 1 commits: kkmpptxz 628e2b00 (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 conflict_content = work_dir.read_file("file1"); insta::assert_snapshot!(conflict_content, @r#" <<<<<<< conflict 1 of 1 %%%%%%% diff from: zzzzzzzz 00000000 (parents of rebased revision) \\\\\\\ to: qpvuntsm e35bcaff "1" (rebase destination) +1a +1b +++++++ kkmpptxz e05db987 (rebased revision) 2a 2b >>>>>>> conflict 1 of 1 ends "#); // Cannot absorb from conflict let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Warning: Skipping file1: Is a conflict Nothing changed. [EOF] "); // Cannot absorb from resolved conflict work_dir.run_jj(["new"]).success(); work_dir.write_file("file1", "1A\n1b\n2a\n2B\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Warning: Skipping file1: Is a conflict Nothing changed. [EOF] ");} #[test]fn test_absorb_deleted_file() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m1"]).success(); work_dir.write_file("file1", "1a\n"); work_dir.write_file("file2", "1a\n"); work_dir.write_file("file3", ""); work_dir.run_jj(["new"]).success(); work_dir.remove_file("file1"); work_dir.write_file("file2", ""); // emptied work_dir.remove_file("file3"); // no content change // Since the destinations are chosen based on content diffs, file3 cannot be // absorbed. let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r"Lines 1–500 of 1137. Load more
// Copyright 2024 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 testutils::TestResult; use crate::common::CommandOutput; use crate::common::TestEnvironment; use crate::common::TestWorkDir; #[test] fn test_absorb_simple() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m0"]).success(); work_dir.write_file("file1", ""); work_dir.run_jj(["new", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n"); work_dir.run_jj(["new", "-m2"]).success(); work_dir.write_file("file1", "1a\n1b\n2a\n2b\n"); // Empty commit work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Nothing changed. [EOF] "); // Insert first and last lines work_dir.write_file("file1", "1X\n1a\n1b\n2a\n2b\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Absorbed changes into 2 revisions: zsuskuln 95568809 2 kkmpptxz bd7d4016 1 Working copy (@) now at: yqosqzyt 977269ac (empty) (no description set) Parent commit (@-) : zsuskuln 95568809 2 [EOF] "); // Modify middle line in hunk work_dir.write_file("file1", "1X\n1A\n1b\n2a\n2b\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 1 revisions: kkmpptxz 5810eb0f 1 Rebased 1 descendant commits. Working copy (@) now at: vruxwmqv 48c7d8fa (empty) (no description set) Parent commit (@-) : zsuskuln 8edd60a2 2 [EOF] "); // Remove middle line from hunk work_dir.write_file("file1", "1X\n1A\n1b\n2a\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Absorbed changes into 1 revisions: zsuskuln dd109863 2 Working copy (@) now at: yostqsxw 7482f74b (empty) (no description set) Parent commit (@-) : zsuskuln dd109863 2 [EOF] "); // Insert ambiguous line in between work_dir.write_file("file1", "1X\n1A\n1b\nY\n2a\n2Z\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Nothing changed. [EOF] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @" @ yostqsxw bde51bc9 (no description set) │ diff --git a/file1 b/file1 │ index 8653ca354d..88eb438902 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,5 +1,6 @@ │ 1X │ 1A │ 1b │ +Y │ 2a │ 2Z ○ zsuskuln dd109863 2 │ diff --git a/file1 b/file1 │ index ed237b5112..8653ca354d 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,3 +1,5 @@ │ 1X │ 1A │ 1b │ +2a │ +2Z ○ kkmpptxz 5810eb0f 1 │ diff --git a/file1 b/file1 │ index e69de29bb2..ed237b5112 100644 │ --- a/file1 │ +++ b/file1 │ @@ -0,0 +1,3 @@ │ +1X │ +1A │ +1b ○ qpvuntsm 6a446874 0 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..e69de29bb2 [EOF] "); insta::assert_snapshot!(get_evolog(&work_dir, "subject(1)"), @" ○ kkmpptxz 5810eb0f 1 ├─╮ │ ○ yqosqzyt/0 39b42898 (hidden) (no description set) │ ○ yqosqzyt/1 977269ac (hidden) (empty) (no description set) ○ kkmpptxz/1 bd7d4016 (hidden) 1 ├─╮ │ ○ mzvwutvl/0 0b307741 (hidden) (no description set) │ ○ mzvwutvl/1 f2709b4e (hidden) (empty) (no description set) ○ kkmpptxz/2 1553c5e8 (hidden) 1 ○ kkmpptxz/3 eb943711 (hidden) (empty) 1 [EOF] "); insta::assert_snapshot!(get_evolog(&work_dir, "subject(2)"), @" ○ zsuskuln dd109863 2 ├─╮ │ ○ vruxwmqv/0 761492a8 (hidden) (no description set) │ ○ vruxwmqv/1 48c7d8fa (hidden) (empty) (no description set) ○ zsuskuln/1 8edd60a2 (hidden) 2 ○ zsuskuln/2 95568809 (hidden) 2 ├─╮ │ ○ mzvwutvl/0 0b307741 (hidden) (no description set) │ ○ mzvwutvl/1 f2709b4e (hidden) (empty) (no description set) ○ zsuskuln/3 36fad385 (hidden) 2 ○ zsuskuln/4 561fbce9 (hidden) (empty) 2 [EOF] "); } #[test] fn test_absorb_replace_single_line_hunk() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m1"]).success(); work_dir.write_file("file1", "1a\n"); work_dir.run_jj(["new", "-m2"]).success(); work_dir.write_file("file1", "2a\n1a\n2b\n"); // Replace single-line hunk, which produces a conflict right now. If our // merge logic were based on interleaved delta, the hunk would be applied // cleanly. work_dir.run_jj(["new"]).success(); work_dir.write_file("file1", "2a\n1A\n2b\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 1 revisions: qpvuntsm 125fba68 (conflict) 1 Rebased 1 descendant commits. Working copy (@) now at: mzvwutvl deeb043a (empty) (no description set) Parent commit (@-) : kkmpptxz 732472fb 2 New conflicts appeared in 1 commits: qpvuntsm 125fba68 (conflict) 1 Hint: To resolve the conflicts, start by creating a commit on top of the conflicted commit: jj new qpvuntsm 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] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r#" @ mzvwutvl deeb043a (empty) (no description set) ○ kkmpptxz 732472fb 2 │ diff --git a/file1 b/file1 │ index 0000000000..2f87e8e465 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,11 +1,3 @@ │ -<<<<<<< conflict 1 of 1 │ -%%%%%%% diff from: kkmpptxz 9d700628 "2" (parents of absorbed revision) │ -\\\\\\\ to: qpvuntsm aa6cb9bc "1" (absorb destination) │ --2a │ - 1a │ --2b │ -+++++++ absorbed changes (from zsuskuln 5d926f12) │ 2a │ 1A │ 2b │ ->>>>>>> conflict 1 of 1 ends × qpvuntsm 125fba68 (conflict) 1 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..0000000000 --- /dev/null +++ b/file1 @@ -0,0 +1,11 @@ +<<<<<<< conflict 1 of 1 +%%%%%%% diff from: kkmpptxz 9d700628 "2" (parents of absorbed revision) +\\\\\\\ to: qpvuntsm aa6cb9bc "1" (absorb destination) +-2a + 1a +-2b ++++++++ absorbed changes (from zsuskuln 5d926f12) +2a +1A +2b +>>>>>>> conflict 1 of 1 ends [EOF] "#); } #[test] fn test_absorb_merge() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m0"]).success(); work_dir.write_file("file1", "0a\n"); work_dir.run_jj(["new", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n0a\n"); work_dir.run_jj(["new", "-m2", "subject(0)"]).success(); work_dir.write_file("file1", "0a\n2a\n2b\n"); let output = work_dir.run_jj(["new", "-m3", "subject(1)", "subject(2)"]); insta::assert_snapshot!(output, @" ------- stderr ------- Working copy (@) now at: mzvwutvl 42875bf7 (empty) 3 Parent commit (@-) : kkmpptxz 9c66f62f 1 Parent commit (@-) : zsuskuln 6a3dcbcf 2 Added 0 files, modified 1 files, removed 0 files [EOF] "); // Modify first and last lines, absorb from merge work_dir.write_file("file1", "1A\n1b\n0a\n2a\n2B\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 2 revisions: zsuskuln a6fde7ea 2 kkmpptxz 00ecc958 1 Rebased 1 descendant commits. Working copy (@) now at: mzvwutvl 30499858 (empty) 3 Parent commit (@-) : kkmpptxz 00ecc958 1 Parent commit (@-) : zsuskuln a6fde7ea 2 [EOF] "); // Add hunk to merge revision work_dir.write_file("file2", "3a\n"); // Absorb into merge work_dir.run_jj(["new"]).success(); work_dir.write_file("file2", "3A\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Absorbed changes into 1 revisions: mzvwutvl faf778a4 3 Working copy (@) now at: vruxwmqv cec519a1 (empty) (no description set) Parent commit (@-) : mzvwutvl faf778a4 3 [EOF] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @" @ vruxwmqv cec519a1 (empty) (no description set) ○ mzvwutvl faf778a4 3 ├─╮ diff --git a/file2 b/file2 │ │ new file mode 100644 │ │ index 0000000000..44442d2d7b │ │ --- /dev/null │ │ +++ b/file2 │ │ @@ -0,0 +1,1 @@ │ │ +3A │ ○ zsuskuln a6fde7ea 2 │ │ diff --git a/file1 b/file1 │ │ index eb6e8821f1..4907935b9f 100644 │ │ --- a/file1 │ │ +++ b/file1 │ │ @@ -1,1 +1,3 @@ │ │ 0a │ │ +2a │ │ +2B ○ │ kkmpptxz 00ecc958 1 ├─╯ diff --git a/file1 b/file1 │ index eb6e8821f1..902dd8ef13 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,1 +1,3 @@ │ +1A │ +1b │ 0a ○ qpvuntsm d4f07be5 0 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..eb6e8821f1 --- /dev/null +++ b/file1 @@ -0,0 +1,1 @@ +0a [EOF] "); } #[test] fn test_absorb_discardable_merge_with_descendant() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m0"]).success(); work_dir.write_file("file1", "0a\n"); work_dir.run_jj(["new", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n0a\n"); work_dir.run_jj(["new", "-m2", "subject(0)"]).success(); work_dir.write_file("file1", "0a\n2a\n2b\n"); let output = work_dir.run_jj(["new", "subject(1)", "subject(2)"]); insta::assert_snapshot!(output, @" ------- stderr ------- Working copy (@) now at: mzvwutvl ad00b91a (empty) (no description set) Parent commit (@-) : kkmpptxz 9c66f62f 1 Parent commit (@-) : zsuskuln 6a3dcbcf 2 Added 0 files, modified 1 files, removed 0 files [EOF] "); // Modify first and last lines in the merge commit work_dir.write_file("file1", "1A\n1b\n0a\n2a\n2B\n"); // Add new commit on top work_dir.run_jj(["new", "-m3"]).success(); work_dir.write_file("file2", "3a\n"); // Then absorb the merge commit let output = work_dir.run_jj(["absorb", "--from=@-"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Absorbed changes into 2 revisions: zsuskuln a6cd8e87 2 kkmpptxz 98b7d214 1 Rebased 1 descendant commits. Working copy (@) now at: royxmykx df946e9b 3 Parent commit (@-) : kkmpptxz 98b7d214 1 Parent commit (@-) : zsuskuln a6cd8e87 2 [EOF] "); insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @" @ royxmykx df946e9b 3 ├─╮ diff --git a/file2 b/file2 │ │ new file mode 100644 │ │ index 0000000000..31cd755d20 │ │ --- /dev/null │ │ +++ b/file2 │ │ @@ -0,0 +1,1 @@ │ │ +3a │ ○ zsuskuln a6cd8e87 2 │ │ diff --git a/file1 b/file1 │ │ index eb6e8821f1..4907935b9f 100644 │ │ --- a/file1 │ │ +++ b/file1 │ │ @@ -1,1 +1,3 @@ │ │ 0a │ │ +2a │ │ +2B ○ │ kkmpptxz 98b7d214 1 ├─╯ diff --git a/file1 b/file1 │ index eb6e8821f1..902dd8ef13 100644 │ --- a/file1 │ +++ b/file1 │ @@ -1,1 +1,3 @@ │ +1A │ +1b │ 0a ○ qpvuntsm d4f07be5 0 │ diff --git a/file1 b/file1 ~ new file mode 100644 index 0000000000..eb6e8821f1 --- /dev/null +++ b/file1 @@ -0,0 +1,1 @@ +0a [EOF] "); } #[test] fn test_absorb_conflict() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m1"]).success(); work_dir.write_file("file1", "1a\n1b\n"); work_dir.run_jj(["new", "root()"]).success(); work_dir.write_file("file1", "2a\n2b\n"); let output = work_dir.run_jj(["rebase", "-r@", "-dsubject(1)"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Rebased 1 commits to destination. Working copy (@) now at: kkmpptxz 628e2b00 (conflict) (no description set) Parent commit (@-) : qpvuntsm e35bcaff 1 Added 0 files, modified 1 files, removed 0 files Warning: There are unresolved conflicts at these paths: file1 2-sided conflict New conflicts appeared in 1 commits: kkmpptxz 628e2b00 (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 conflict_content = work_dir.read_file("file1"); insta::assert_snapshot!(conflict_content, @r#" <<<<<<< conflict 1 of 1 %%%%%%% diff from: zzzzzzzz 00000000 (parents of rebased revision) \\\\\\\ to: qpvuntsm e35bcaff "1" (rebase destination) +1a +1b +++++++ kkmpptxz e05db987 (rebased revision) 2a 2b >>>>>>> conflict 1 of 1 ends "#); // Cannot absorb from conflict let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Warning: Skipping file1: Is a conflict Nothing changed. [EOF] "); // Cannot absorb from resolved conflict work_dir.run_jj(["new"]).success(); work_dir.write_file("file1", "1A\n1b\n2a\n2B\n"); let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @" ------- stderr ------- Warning: Skipping file1: Is a conflict Nothing changed. [EOF] "); } #[test] fn test_absorb_deleted_file() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir.run_jj(["describe", "-m1"]).success(); work_dir.write_file("file1", "1a\n"); work_dir.write_file("file2", "1a\n"); work_dir.write_file("file3", ""); work_dir.run_jj(["new"]).success(); work_dir.remove_file("file1"); work_dir.write_file("file2", ""); // emptied work_dir.remove_file("file3"); // no content change // Since the destinations are chosen based on content diffs, file3 cannot be // absorbed. let output = work_dir.run_jj(["absorb"]); insta::assert_snapshot!(output, @r"