just playing with tangled
at ig/vimdiffwarn 589 lines 20 kB view raw
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::create_commit_with_files; 16use crate::common::CommandOutput; 17use crate::common::TestEnvironment; 18use crate::common::TestWorkDir; 19 20#[test] 21fn test_restore() { 22 let test_env = TestEnvironment::default(); 23 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 24 let work_dir = test_env.work_dir("repo"); 25 26 work_dir.write_file("file1", "a\n"); 27 work_dir.run_jj(["new"]).success(); 28 work_dir.write_file("file2", "b\n"); 29 work_dir.run_jj(["new"]).success(); 30 work_dir.remove_file("file1"); 31 work_dir.write_file("file2", "c\n"); 32 work_dir.write_file("file3", "c\n"); 33 34 // There is no `-r` argument 35 let output = work_dir.run_jj(["restore", "-r=@-"]); 36 insta::assert_snapshot!(output, @r" 37 ------- stderr ------- 38 Error: `jj restore` does not have a `--revision`/`-r` option. If you'd like to modify 39 the *current* revision, use `--from`. If you'd like to modify a *different* revision, 40 use `--into` or `--changes-in`. 41 [EOF] 42 [exit status: 1] 43 "); 44 45 // Restores from parent by default 46 let output = work_dir.run_jj(["restore"]); 47 insta::assert_snapshot!(output, @r" 48 ------- stderr ------- 49 Created kkmpptxz 370d81ea (empty) (no description set) 50 Working copy (@) now at: kkmpptxz 370d81ea (empty) (no description set) 51 Parent commit (@-) : rlvkpnrz ef160660 (no description set) 52 Added 1 files, modified 1 files, removed 1 files 53 [EOF] 54 "); 55 let output = work_dir.run_jj(["diff", "-s"]); 56 insta::assert_snapshot!(output, @""); 57 58 // Can restore another revision from its parents 59 work_dir.run_jj(["undo"]).success(); 60 let output = work_dir.run_jj(["diff", "-s", "-r=@-"]); 61 insta::assert_snapshot!(output, @r" 62 A file2 63 [EOF] 64 "); 65 let output = work_dir.run_jj(["restore", "-c=@-"]); 66 insta::assert_snapshot!(output, @r" 67 ------- stderr ------- 68 Created rlvkpnrz b9b6011e (empty) (no description set) 69 Rebased 1 descendant commits 70 Working copy (@) now at: kkmpptxz 5b361547 (conflict) (no description set) 71 Parent commit (@-) : rlvkpnrz b9b6011e (empty) (no description set) 72 Added 0 files, modified 1 files, removed 0 files 73 Warning: There are unresolved conflicts at these paths: 74 file2 2-sided conflict including 1 deletion 75 New conflicts appeared in 1 commits: 76 kkmpptxz 5b361547 (conflict) (no description set) 77 Hint: To resolve the conflicts, start by updating to it: 78 jj new kkmpptxz 79 Then use `jj resolve`, or edit the conflict markers in the file directly. 80 Once the conflicts are resolved, you may want to inspect the result with `jj diff`. 81 Then run `jj squash` to move the resolution into the conflicted commit. 82 [EOF] 83 "); 84 let output = work_dir.run_jj(["diff", "-s", "-r=@-"]); 85 insta::assert_snapshot!(output, @""); 86 87 // Can restore this revision from another revision 88 work_dir.run_jj(["undo"]).success(); 89 let output = work_dir.run_jj(["restore", "--from", "@--"]); 90 insta::assert_snapshot!(output, @r" 91 ------- stderr ------- 92 Created kkmpptxz 1154634b (no description set) 93 Working copy (@) now at: kkmpptxz 1154634b (no description set) 94 Parent commit (@-) : rlvkpnrz ef160660 (no description set) 95 Added 1 files, modified 0 files, removed 2 files 96 [EOF] 97 "); 98 let output = work_dir.run_jj(["diff", "-s"]); 99 insta::assert_snapshot!(output, @r" 100 D file2 101 [EOF] 102 "); 103 104 // Can restore into other revision 105 work_dir.run_jj(["undo"]).success(); 106 let output = work_dir.run_jj(["restore", "--into", "@-"]); 107 insta::assert_snapshot!(output, @r" 108 ------- stderr ------- 109 Created rlvkpnrz ad805965 (no description set) 110 Rebased 1 descendant commits 111 Working copy (@) now at: kkmpptxz 3fcdcbf2 (empty) (no description set) 112 Parent commit (@-) : rlvkpnrz ad805965 (no description set) 113 [EOF] 114 "); 115 let output = work_dir.run_jj(["diff", "-s"]); 116 insta::assert_snapshot!(output, @""); 117 let output = work_dir.run_jj(["diff", "-s", "-r", "@-"]); 118 insta::assert_snapshot!(output, @r" 119 D file1 120 A file2 121 A file3 122 [EOF] 123 "); 124 125 // Can combine `--from` and `--into` 126 work_dir.run_jj(["undo"]).success(); 127 let output = work_dir.run_jj(["restore", "--from", "@", "--into", "@-"]); 128 insta::assert_snapshot!(output, @r" 129 ------- stderr ------- 130 Created rlvkpnrz f256040a (no description set) 131 Rebased 1 descendant commits 132 Working copy (@) now at: kkmpptxz 9c6f2083 (empty) (no description set) 133 Parent commit (@-) : rlvkpnrz f256040a (no description set) 134 [EOF] 135 "); 136 let output = work_dir.run_jj(["diff", "-s"]); 137 insta::assert_snapshot!(output, @""); 138 let output = work_dir.run_jj(["diff", "-s", "-r", "@-"]); 139 insta::assert_snapshot!(output, @r" 140 D file1 141 A file2 142 A file3 143 [EOF] 144 "); 145 146 // Can restore only specified paths 147 work_dir.run_jj(["undo"]).success(); 148 let output = work_dir.run_jj(["restore", "file2", "file3"]); 149 insta::assert_snapshot!(output, @r" 150 ------- stderr ------- 151 Created kkmpptxz 4ad35a2f (no description set) 152 Working copy (@) now at: kkmpptxz 4ad35a2f (no description set) 153 Parent commit (@-) : rlvkpnrz ef160660 (no description set) 154 Added 0 files, modified 1 files, removed 1 files 155 [EOF] 156 "); 157 let output = work_dir.run_jj(["diff", "-s"]); 158 insta::assert_snapshot!(output, @r" 159 D file1 160 [EOF] 161 "); 162} 163 164// Much of this test is copied from test_resolve_command 165#[test] 166fn test_restore_conflicted_merge() { 167 let test_env = TestEnvironment::default(); 168 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 169 let work_dir = test_env.work_dir("repo"); 170 171 create_commit_with_files(&work_dir, "base", &[], &[("file", "base\n")]); 172 create_commit_with_files(&work_dir, "a", &["base"], &[("file", "a\n")]); 173 create_commit_with_files(&work_dir, "b", &["base"], &[("file", "b\n")]); 174 create_commit_with_files(&work_dir, "conflict", &["a", "b"], &[]); 175 // Test the setup 176 insta::assert_snapshot!(get_log_output(&work_dir), @r" 177 @ conflict 178 ├─╮ 179 │ ○ b 180 ○ │ a 181 ├─╯ 182 ○ base 183184 [EOF] 185 "); 186 insta::assert_snapshot!(work_dir.read_file("file"), @r" 187 <<<<<<< Conflict 1 of 1 188 %%%%%%% Changes from base to side #1 189 -base 190 +a 191 +++++++ Contents of side #2 192 b 193 >>>>>>> Conflict 1 of 1 ends 194 "); 195 196 // Overwrite the file... 197 work_dir.write_file("file", "resolution"); 198 insta::assert_snapshot!(work_dir.run_jj(["diff"]), @r" 199 Resolved conflict in file: 200 1 : <<<<<<< Conflict 1 of 1 201 2 : %%%%%%% Changes from base to side #1 202 3 : -base 203 4 : +a 204 5 : +++++++ Contents of side #2 205 6 : b 206 7 : >>>>>>> Conflict 1 of 1 ends 207 1: resolution 208 [EOF] 209 "); 210 211 // ...and restore it back again. 212 let output = work_dir.run_jj(["restore", "file"]); 213 insta::assert_snapshot!(output, @r" 214 ------- stderr ------- 215 Created vruxwmqv 25a37060 conflict | (conflict) (empty) conflict 216 Working copy (@) now at: vruxwmqv 25a37060 conflict | (conflict) (empty) conflict 217 Parent commit (@-) : zsuskuln aa493daf a | a 218 Parent commit (@-) : royxmykx db6a4daf b | b 219 Added 0 files, modified 1 files, removed 0 files 220 Warning: There are unresolved conflicts at these paths: 221 file 2-sided conflict 222 [EOF] 223 "); 224 insta::assert_snapshot!(work_dir.read_file("file"), @r" 225 <<<<<<< Conflict 1 of 1 226 %%%%%%% Changes from base to side #1 227 -base 228 +a 229 +++++++ Contents of side #2 230 b 231 >>>>>>> Conflict 1 of 1 ends 232 "); 233 let output = work_dir.run_jj(["diff"]); 234 insta::assert_snapshot!(output, @""); 235 236 // The same, but without the `file` argument. Overwrite the file... 237 work_dir.write_file("file", "resolution"); 238 insta::assert_snapshot!(work_dir.run_jj(["diff"]), @r" 239 Resolved conflict in file: 240 1 : <<<<<<< Conflict 1 of 1 241 2 : %%%%%%% Changes from base to side #1 242 3 : -base 243 4 : +a 244 5 : +++++++ Contents of side #2 245 6 : b 246 7 : >>>>>>> Conflict 1 of 1 ends 247 1: resolution 248 [EOF] 249 "); 250 251 // ... and restore it back again. 252 let output = work_dir.run_jj(["restore"]); 253 insta::assert_snapshot!(output, @r" 254 ------- stderr ------- 255 Created vruxwmqv f2c82b9c conflict | (conflict) (empty) conflict 256 Working copy (@) now at: vruxwmqv f2c82b9c conflict | (conflict) (empty) conflict 257 Parent commit (@-) : zsuskuln aa493daf a | a 258 Parent commit (@-) : royxmykx db6a4daf b | b 259 Added 0 files, modified 1 files, removed 0 files 260 Warning: There are unresolved conflicts at these paths: 261 file 2-sided conflict 262 [EOF] 263 "); 264 insta::assert_snapshot!(work_dir.read_file("file"), @r" 265 <<<<<<< Conflict 1 of 1 266 %%%%%%% Changes from base to side #1 267 -base 268 +a 269 +++++++ Contents of side #2 270 b 271 >>>>>>> Conflict 1 of 1 ends 272 "); 273} 274 275#[test] 276fn test_restore_restore_descendants() { 277 let test_env = TestEnvironment::default(); 278 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 279 let work_dir = test_env.work_dir("repo"); 280 281 create_commit_with_files(&work_dir, "base", &[], &[("file", "base\n")]); 282 create_commit_with_files(&work_dir, "a", &["base"], &[("file", "a\n")]); 283 create_commit_with_files( 284 &work_dir, 285 "b", 286 &["base"], 287 &[("file", "b\n"), ("file2", "b\n")], 288 ); 289 create_commit_with_files(&work_dir, "ab", &["a", "b"], &[("file", "ab\n")]); 290 // Test the setup 291 insta::assert_snapshot!(get_log_output(&work_dir), @r" 292 @ ab 293 ├─╮ 294 │ ○ b 295 ○ │ a 296 ├─╯ 297 ○ base 298299 [EOF] 300 "); 301 insta::assert_snapshot!(work_dir.read_file("file"), @"ab"); 302 303 // Commit "b" was not supposed to modify "file", restore it from its parent 304 // while preserving its child commit content. 305 let output = work_dir.run_jj(["restore", "-c", "b", "file", "--restore-descendants"]); 306 insta::assert_snapshot!(output, @r" 307 ------- stderr ------- 308 Created royxmykx 3fd5aa05 b | b 309 Rebased 1 descendant commits (while preserving their content) 310 Working copy (@) now at: vruxwmqv bf5491a0 ab | ab 311 Parent commit (@-) : zsuskuln aa493daf a | a 312 Parent commit (@-) : royxmykx 3fd5aa05 b | b 313 [EOF] 314 "); 315 316 // Check that "a", "b", and "ab" have their expected content by diffing them. 317 // "ab" must have kept its content. 318 insta::assert_snapshot!(work_dir.run_jj(["diff", "--from=a", "--to=ab", "--git"]), @r" 319 diff --git a/file b/file 320 index 7898192261..81bf396956 100644 321 --- a/file 322 +++ b/file 323 @@ -1,1 +1,1 @@ 324 -a 325 +ab 326 diff --git a/file2 b/file2 327 new file mode 100644 328 index 0000000000..6178079822 329 --- /dev/null 330 +++ b/file2 331 @@ -0,0 +1,1 @@ 332 +b 333 [EOF] 334 "); 335 insta::assert_snapshot!(work_dir.run_jj(["diff", "--from=b", "--to=ab", "--git"]), @r" 336 diff --git a/file b/file 337 index df967b96a5..81bf396956 100644 338 --- a/file 339 +++ b/file 340 @@ -1,1 +1,1 @@ 341 -base 342 +ab 343 [EOF] 344 "); 345} 346 347#[test] 348fn test_restore_interactive() { 349 let mut test_env = TestEnvironment::default(); 350 let diff_editor = test_env.set_up_fake_diff_editor(); 351 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 352 let work_dir = test_env.work_dir("repo"); 353 354 create_commit_with_files(&work_dir, "a", &[], &[("file1", "a1\n"), ("file2", "a2\n")]); 355 create_commit_with_files( 356 &work_dir, 357 "b", 358 &["a"], 359 &[("file1", "b1\n"), ("file2", "b2\n"), ("file3", "b3\n")], 360 ); 361 let output = work_dir.run_jj(["log", "--summary"]); 362 insta::assert_snapshot!(output, @r" 363 @ zsuskuln test.user@example.com 2001-02-03 08:05:11 b c0745ce2 364 │ b 365 │ M file1 366 │ M file2 367 │ A file3 368 ○ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 186caaef 369 │ a 370 │ A file1 371 │ A file2 372 ◆ zzzzzzzz root() 00000000 373 [EOF] 374 "); 375 376 let diff_script = [ 377 "files-before file1 file2 file3", 378 "files-after JJ-INSTRUCTIONS file1 file2", 379 "reset file2", 380 "dump JJ-INSTRUCTIONS instrs", 381 ] 382 .join("\0"); 383 std::fs::write(diff_editor, diff_script).unwrap(); 384 385 // Restore file1 and file3 386 let output = work_dir.run_jj(["restore", "-i", "--from=@-"]); 387 insta::assert_snapshot!(output, @r" 388 ------- stderr ------- 389 Created zsuskuln bccde490 b | b 390 Working copy (@) now at: zsuskuln bccde490 b | b 391 Parent commit (@-) : rlvkpnrz 186caaef a | a 392 Added 0 files, modified 1 files, removed 1 files 393 [EOF] 394 "); 395 396 insta::assert_snapshot!( 397 std::fs::read_to_string(test_env.env_root().join("instrs")).unwrap(), @r" 398 You are restoring changes from: rlvkpnrz 186caaef a | a 399 to commit: zsuskuln c0745ce2 b | b 400 401 The diff initially shows all changes restored. Adjust the right side until it 402 shows the contents you want for the destination commit. 403 "); 404 405 let output = work_dir.run_jj(["log", "--summary"]); 406 insta::assert_snapshot!(output, @r" 407 @ zsuskuln test.user@example.com 2001-02-03 08:05:13 b bccde490 408 │ b 409 │ M file2 410 ○ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 186caaef 411 │ a 412 │ A file1 413 │ A file2 414 ◆ zzzzzzzz root() 00000000 415 [EOF] 416 "); 417 418 // Try again with --tool, which should imply --interactive 419 work_dir.run_jj(["undo"]).success(); 420 let output = work_dir.run_jj(["restore", "--tool=fake-diff-editor"]); 421 insta::assert_snapshot!(output, @r" 422 ------- stderr ------- 423 Created zsuskuln 5921de19 b | b 424 Working copy (@) now at: zsuskuln 5921de19 b | b 425 Parent commit (@-) : rlvkpnrz 186caaef a | a 426 Added 0 files, modified 1 files, removed 1 files 427 [EOF] 428 "); 429 430 let output = work_dir.run_jj(["log", "--summary"]); 431 insta::assert_snapshot!(output, @r" 432 @ zsuskuln test.user@example.com 2001-02-03 08:05:16 b 5921de19 433 │ b 434 │ M file2 435 ○ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 186caaef 436 │ a 437 │ A file1 438 │ A file2 439 ◆ zzzzzzzz root() 00000000 440 [EOF] 441 "); 442} 443 444#[test] 445fn test_restore_interactive_merge() { 446 let mut test_env = TestEnvironment::default(); 447 let diff_editor = test_env.set_up_fake_diff_editor(); 448 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 449 let work_dir = test_env.work_dir("repo"); 450 451 create_commit_with_files(&work_dir, "a", &[], &[("file1", "a1\n")]); 452 create_commit_with_files(&work_dir, "b", &[], &[("file2", "b1\n")]); 453 create_commit_with_files( 454 &work_dir, 455 "c", 456 &["a", "b"], 457 &[("file1", "c1\n"), ("file2", "c2\n"), ("file3", "c3\n")], 458 ); 459 let output = work_dir.run_jj(["log", "--summary"]); 460 insta::assert_snapshot!(output, @r" 461 @ royxmykx test.user@example.com 2001-02-03 08:05:13 c 34042291 462 ├─╮ c 463 │ │ M file1 464 │ │ M file2 465 │ │ A file3 466 │ ○ zsuskuln test.user@example.com 2001-02-03 08:05:11 b 29e70804 467 │ │ b 468 │ │ A file2 469 ○ │ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 79c1b823 470 ├─╯ a 471 │ A file1 472 ◆ zzzzzzzz root() 00000000 473 [EOF] 474 "); 475 476 let diff_script = [ 477 "files-before file1 file2 file3", 478 "files-after JJ-INSTRUCTIONS file1 file2", 479 "reset file2", 480 "dump JJ-INSTRUCTIONS instrs", 481 ] 482 .join("\0"); 483 std::fs::write(diff_editor, diff_script).unwrap(); 484 485 // Restore file1 and file3 486 let output = work_dir.run_jj(["restore", "-i"]); 487 insta::assert_snapshot!(output, @r" 488 ------- stderr ------- 489 Created royxmykx 72e0cbf4 c | c 490 Working copy (@) now at: royxmykx 72e0cbf4 c | c 491 Parent commit (@-) : rlvkpnrz 79c1b823 a | a 492 Parent commit (@-) : zsuskuln 29e70804 b | b 493 Added 0 files, modified 1 files, removed 1 files 494 [EOF] 495 "); 496 497 insta::assert_snapshot!( 498 std::fs::read_to_string(test_env.env_root().join("instrs")).unwrap(), @r" 499 You are restoring changes from: rlvkpnrz 79c1b823 a | a 500 zsuskuln 29e70804 b | b 501 to commit: royxmykx 34042291 c | c 502 503 The diff initially shows all changes restored. Adjust the right side until it 504 shows the contents you want for the destination commit. 505 "); 506 507 let output = work_dir.run_jj(["log", "--summary"]); 508 insta::assert_snapshot!(output, @r" 509 @ royxmykx test.user@example.com 2001-02-03 08:05:15 c 72e0cbf4 510 ├─╮ c 511 │ │ M file2 512 │ ○ zsuskuln test.user@example.com 2001-02-03 08:05:11 b 29e70804 513 │ │ b 514 │ │ A file2 515 ○ │ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 79c1b823 516 ├─╯ a 517 │ A file1 518 ◆ zzzzzzzz root() 00000000 519 [EOF] 520 "); 521} 522 523#[test] 524fn test_restore_interactive_with_paths() { 525 let mut test_env = TestEnvironment::default(); 526 let diff_editor = test_env.set_up_fake_diff_editor(); 527 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 528 let work_dir = test_env.work_dir("repo"); 529 530 create_commit_with_files(&work_dir, "a", &[], &[("file1", "a1\n"), ("file2", "a2\n")]); 531 create_commit_with_files( 532 &work_dir, 533 "b", 534 &["a"], 535 &[("file1", "b1\n"), ("file2", "b2\n"), ("file3", "b3\n")], 536 ); 537 let output = work_dir.run_jj(["log", "--summary"]); 538 insta::assert_snapshot!(output, @r" 539 @ zsuskuln test.user@example.com 2001-02-03 08:05:11 b c0745ce2 540 │ b 541 │ M file1 542 │ M file2 543 │ A file3 544 ○ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 186caaef 545 │ a 546 │ A file1 547 │ A file2 548 ◆ zzzzzzzz root() 00000000 549 [EOF] 550 "); 551 552 let diff_script = [ 553 "files-before file1 file2", 554 "files-after JJ-INSTRUCTIONS file1 file2", 555 "reset file2", 556 ] 557 .join("\0"); 558 std::fs::write(diff_editor, diff_script).unwrap(); 559 560 // Restore file1 (file2 is reset by interactive editor) 561 let output = work_dir.run_jj(["restore", "-i", "file1", "file2"]); 562 insta::assert_snapshot!(output, @r" 563 ------- stderr ------- 564 Created zsuskuln 7187da33 b | b 565 Working copy (@) now at: zsuskuln 7187da33 b | b 566 Parent commit (@-) : rlvkpnrz 186caaef a | a 567 Added 0 files, modified 1 files, removed 0 files 568 [EOF] 569 "); 570 571 let output = work_dir.run_jj(["log", "--summary"]); 572 insta::assert_snapshot!(output, @r" 573 @ zsuskuln test.user@example.com 2001-02-03 08:05:13 b 7187da33 574 │ b 575 │ M file2 576 │ A file3 577 ○ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 a 186caaef 578 │ a 579 │ A file1 580 │ A file2 581 ◆ zzzzzzzz root() 00000000 582 [EOF] 583 "); 584} 585 586#[must_use] 587fn get_log_output(work_dir: &TestWorkDir) -> CommandOutput { 588 work_dir.run_jj(["log", "-T", "bookmarks"]) 589}