just playing with tangled
1// Copyright 2022 The Jujutsu Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::common::TestEnvironment;
16
17pub mod common;
18
19#[test]
20fn test_diffedit() {
21 let mut test_env = TestEnvironment::default();
22 test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
23 let repo_path = test_env.env_root().join("repo");
24
25 std::fs::write(repo_path.join("file1"), "a\n").unwrap();
26 test_env.jj_cmd_success(&repo_path, &["new"]);
27 std::fs::write(repo_path.join("file2"), "a\n").unwrap();
28 std::fs::write(repo_path.join("file3"), "a\n").unwrap();
29 test_env.jj_cmd_success(&repo_path, &["new"]);
30 std::fs::remove_file(repo_path.join("file1")).unwrap();
31 std::fs::write(repo_path.join("file2"), "b\n").unwrap();
32
33 let edit_script = test_env.set_up_fake_diff_editor();
34
35 // Nothing happens if we make no changes
36 std::fs::write(
37 &edit_script,
38 "files-before file1 file2\0files-after JJ-INSTRUCTIONS file2",
39 )
40 .unwrap();
41 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit"]);
42 insta::assert_snapshot!(stdout, @r###"
43 Nothing changed.
44 "###);
45 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
46 insta::assert_snapshot!(stdout, @r###"
47 R file1
48 M file2
49 "###);
50
51 // Nothing happens if the diff-editor exits with an error
52 std::fs::write(&edit_script, "rm file2\0fail").unwrap();
53 insta::assert_snapshot!(&test_env.jj_cmd_failure(&repo_path, &["diffedit"]), @r###"
54 Error: Failed to edit diff: Tool exited with a non-zero code (run with --verbose to see the exact invocation). Exit code: 1.
55 "###);
56 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
57 insta::assert_snapshot!(stdout, @r###"
58 R file1
59 M file2
60 "###);
61
62 // Can edit changes to individual files
63 std::fs::write(&edit_script, "reset file2").unwrap();
64 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit"]);
65 insta::assert_snapshot!(stdout, @r###"
66 Created 1930da4a57e9 (no description set)
67 Working copy now at: 1930da4a57e9 (no description set)
68 Parent commit : 613028a4693c (no description set)
69 Added 0 files, modified 1 files, removed 0 files
70 "###);
71 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
72 insta::assert_snapshot!(stdout, @r###"
73 R file1
74 "###);
75
76 // Changes to a commit are propagated to descendants
77 test_env.jj_cmd_success(&repo_path, &["undo"]);
78 std::fs::write(&edit_script, "write file3\nmodified\n").unwrap();
79 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit", "-r", "@-"]);
80 insta::assert_snapshot!(stdout, @r###"
81 Created c03ae96780b6 (no description set)
82 Rebased 1 descendant commits
83 Working copy now at: 2a4dc204a6ab (no description set)
84 Parent commit : c03ae96780b6 (no description set)
85 Added 0 files, modified 1 files, removed 0 files
86 "###);
87 let contents = String::from_utf8(std::fs::read(repo_path.join("file3")).unwrap()).unwrap();
88 insta::assert_snapshot!(contents, @r###"
89 modified
90 "###);
91
92 // Test diffedit --from @--
93 test_env.jj_cmd_success(&repo_path, &["undo"]);
94 std::fs::write(
95 &edit_script,
96 "files-before file1\0files-after JJ-INSTRUCTIONS file2 file3\0reset file2",
97 )
98 .unwrap();
99 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit", "--from", "@--"]);
100 insta::assert_snapshot!(stdout, @r###"
101 Created 15f2c966d508 (no description set)
102 Working copy now at: 15f2c966d508 (no description set)
103 Parent commit : 613028a4693c (no description set)
104 Added 0 files, modified 0 files, removed 1 files
105 "###);
106 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
107 insta::assert_snapshot!(stdout, @r###"
108 R file1
109 R file2
110 "###);
111}
112
113#[test]
114fn test_diffedit_merge() {
115 let mut test_env = TestEnvironment::default();
116 test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
117 let repo_path = test_env.env_root().join("repo");
118
119 std::fs::write(repo_path.join("file1"), "a\n").unwrap();
120 std::fs::write(repo_path.join("file2"), "a\n").unwrap();
121 test_env.jj_cmd_success(&repo_path, &["new"]);
122 test_env.jj_cmd_success(&repo_path, &["branch", "create", "b"]);
123 std::fs::write(repo_path.join("file1"), "b\n").unwrap();
124 std::fs::write(repo_path.join("file2"), "b\n").unwrap();
125 test_env.jj_cmd_success(&repo_path, &["co", "@-"]);
126 test_env.jj_cmd_success(&repo_path, &["new"]);
127 std::fs::write(repo_path.join("file1"), "c\n").unwrap();
128 std::fs::write(repo_path.join("file2"), "c\n").unwrap();
129 test_env.jj_cmd_success(&repo_path, &["new", "@", "b", "-m", "merge"]);
130 // Resolve the conflict in file1, but leave the conflict in file2
131 std::fs::write(repo_path.join("file1"), "d\n").unwrap();
132 std::fs::write(repo_path.join("file3"), "d\n").unwrap();
133 test_env.jj_cmd_success(&repo_path, &["new"]);
134 // Test the setup
135 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-r", "@-", "-s"]);
136 insta::assert_snapshot!(stdout, @r###"
137 M file1
138 A file3
139 "###);
140
141 let edit_script = test_env.set_up_fake_diff_editor();
142
143 // Remove file1. The conflict remains in the working copy on top of the merge.
144 std::fs::write(
145 edit_script,
146 "files-before file1\0files-after JJ-INSTRUCTIONS file1 file3\0rm file1",
147 )
148 .unwrap();
149 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit", "-r", "@-"]);
150 insta::assert_snapshot!(stdout, @r###"
151 Created a70eded7af9e merge
152 Rebased 1 descendant commits
153 Working copy now at: a5f1ce845f74 (empty) (no description set)
154 Parent commit : a70eded7af9e merge
155 Added 0 files, modified 0 files, removed 1 files
156 "###);
157 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s", "-r", "@-"]);
158 insta::assert_snapshot!(stdout, @r###"
159 R file1
160 A file3
161 "###);
162 assert!(!repo_path.join("file1").exists());
163 let stdout = test_env.jj_cmd_success(&repo_path, &["print", "file2"]);
164 insta::assert_snapshot!(stdout, @r###"
165 <<<<<<<
166 %%%%%%%
167 -a
168 +c
169 +++++++
170 b
171 >>>>>>>
172 "###);
173}
174
175#[test]
176fn test_diffedit_old_restore_interactive_tests() {
177 let mut test_env = TestEnvironment::default();
178 test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
179 let repo_path = test_env.env_root().join("repo");
180
181 std::fs::write(repo_path.join("file1"), "a\n").unwrap();
182 std::fs::write(repo_path.join("file2"), "a\n").unwrap();
183 test_env.jj_cmd_success(&repo_path, &["new"]);
184 std::fs::remove_file(repo_path.join("file1")).unwrap();
185 std::fs::write(repo_path.join("file2"), "b\n").unwrap();
186 std::fs::write(repo_path.join("file3"), "b\n").unwrap();
187
188 let edit_script = test_env.set_up_fake_diff_editor();
189
190 // Nothing happens if we make no changes
191 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit", "--from", "@-"]);
192 insta::assert_snapshot!(stdout, @r###"
193 Nothing changed.
194 "###);
195 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
196 insta::assert_snapshot!(stdout, @r###"
197 R file1
198 M file2
199 A file3
200 "###);
201
202 // Nothing happens if the diff-editor exits with an error
203 std::fs::write(&edit_script, "rm file2\0fail").unwrap();
204 insta::assert_snapshot!(&test_env.jj_cmd_failure(&repo_path, &["diffedit", "--from", "@-"]), @r###"
205 Error: Failed to edit diff: Tool exited with a non-zero code (run with --verbose to see the exact invocation). Exit code: 1.
206 "###);
207 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
208 insta::assert_snapshot!(stdout, @r###"
209 R file1
210 M file2
211 A file3
212 "###);
213
214 // Can restore changes to individual files
215 std::fs::write(&edit_script, "reset file2\0reset file3").unwrap();
216 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit", "--from", "@-"]);
217 insta::assert_snapshot!(stdout, @r###"
218 Created abdbf6271a1c (no description set)
219 Working copy now at: abdbf6271a1c (no description set)
220 Parent commit : 2375fa164210 (no description set)
221 Added 0 files, modified 1 files, removed 1 files
222 "###);
223 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
224 insta::assert_snapshot!(stdout, @r###"
225 R file1
226 "###);
227
228 // Can make unrelated edits
229 test_env.jj_cmd_success(&repo_path, &["undo"]);
230 std::fs::write(&edit_script, "write file3\nunrelated\n").unwrap();
231 let stdout = test_env.jj_cmd_success(&repo_path, &["diffedit", "--from", "@-"]);
232 insta::assert_snapshot!(stdout, @r###"
233 Created e31f7f33ad07 (no description set)
234 Working copy now at: e31f7f33ad07 (no description set)
235 Parent commit : 2375fa164210 (no description set)
236 Added 0 files, modified 1 files, removed 0 files
237 "###);
238 let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "--git"]);
239 insta::assert_snapshot!(stdout, @r###"
240 diff --git a/file1 b/file1
241 deleted file mode 100644
242 index 7898192261..0000000000
243 --- a/file1
244 +++ /dev/null
245 @@ -1,1 +1,0 @@
246 -a
247 diff --git a/file2 b/file2
248 index 7898192261...6178079822 100644
249 --- a/file2
250 +++ b/file2
251 @@ -1,1 +1,1 @@
252 -a
253 +b
254 diff --git a/file3 b/file3
255 new file mode 100644
256 index 0000000000..c21c9352f7
257 --- /dev/null
258 +++ b/file3
259 @@ -1,0 +1,1 @@
260 +unrelated
261 "###);
262}