just playing with tangled
at ig/vimdiffwarn 805 lines 25 kB view raw
1// Copyright 2024 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::CommandOutput; 16use crate::common::TestEnvironment; 17use crate::common::TestWorkDir; 18 19#[test] 20fn test_absorb_simple() { 21 let test_env = TestEnvironment::default(); 22 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 23 let work_dir = test_env.work_dir("repo"); 24 25 work_dir.run_jj(["describe", "-m0"]).success(); 26 work_dir.write_file("file1", ""); 27 28 work_dir.run_jj(["new", "-m1"]).success(); 29 work_dir.write_file("file1", "1a\n1b\n"); 30 31 work_dir.run_jj(["new", "-m2"]).success(); 32 work_dir.write_file("file1", "1a\n1b\n2a\n2b\n"); 33 34 // Empty commit 35 work_dir.run_jj(["new"]).success(); 36 let output = work_dir.run_jj(["absorb"]); 37 insta::assert_snapshot!(output, @r" 38 ------- stderr ------- 39 Nothing changed. 40 [EOF] 41 "); 42 43 // Insert first and last lines 44 work_dir.write_file("file1", "1X\n1a\n1b\n2a\n2b\n2Z\n"); 45 let output = work_dir.run_jj(["absorb"]); 46 insta::assert_snapshot!(output, @r" 47 ------- stderr ------- 48 Absorbed changes into 2 revisions: 49 zsuskuln 3027ca7a 2 50 kkmpptxz d0f1e8dd 1 51 Working copy (@) now at: yqosqzyt 277bed24 (empty) (no description set) 52 Parent commit (@-) : zsuskuln 3027ca7a 2 53 [EOF] 54 "); 55 56 // Modify middle line in hunk 57 work_dir.write_file("file1", "1X\n1A\n1b\n2a\n2b\n2Z\n"); 58 let output = work_dir.run_jj(["absorb"]); 59 insta::assert_snapshot!(output, @r" 60 ------- stderr ------- 61 Absorbed changes into 1 revisions: 62 kkmpptxz d366d92c 1 63 Rebased 1 descendant commits. 64 Working copy (@) now at: vruxwmqv 32eb72fe (empty) (no description set) 65 Parent commit (@-) : zsuskuln 5bf0bc06 2 66 [EOF] 67 "); 68 69 // Remove middle line from hunk 70 work_dir.write_file("file1", "1X\n1A\n1b\n2a\n2Z\n"); 71 let output = work_dir.run_jj(["absorb"]); 72 insta::assert_snapshot!(output, @r" 73 ------- stderr ------- 74 Absorbed changes into 1 revisions: 75 zsuskuln 6e2c4777 2 76 Working copy (@) now at: yostqsxw 4a48490c (empty) (no description set) 77 Parent commit (@-) : zsuskuln 6e2c4777 2 78 [EOF] 79 "); 80 81 // Insert ambiguous line in between 82 work_dir.write_file("file1", "1X\n1A\n1b\nY\n2a\n2Z\n"); 83 let output = work_dir.run_jj(["absorb"]); 84 insta::assert_snapshot!(output, @r" 85 ------- stderr ------- 86 Nothing changed. 87 [EOF] 88 "); 89 90 insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r" 91 @ yostqsxw 80965bcc (no description set) 92 │ diff --git a/file1 b/file1 93 │ index 8653ca354d..88eb438902 100644 94 │ --- a/file1 95 │ +++ b/file1 96 │ @@ -1,5 +1,6 @@ 97 │ 1X 98 │ 1A 99 │ 1b 100 │ +Y 101 │ 2a 102 │ 2Z 103 ○ zsuskuln 6e2c4777 2 104 │ diff --git a/file1 b/file1 105 │ index ed237b5112..8653ca354d 100644 106 │ --- a/file1 107 │ +++ b/file1 108 │ @@ -1,3 +1,5 @@ 109 │ 1X 110 │ 1A 111 │ 1b 112 │ +2a 113 │ +2Z 114 ○ kkmpptxz d366d92c 1 115 │ diff --git a/file1 b/file1 116 │ index e69de29bb2..ed237b5112 100644 117 │ --- a/file1 118 │ +++ b/file1 119 │ @@ -0,0 +1,3 @@ 120 │ +1X 121 │ +1A 122 │ +1b 123 ○ qpvuntsm 1a4edb91 0 124 │ diff --git a/file1 b/file1 125 ~ new file mode 100644 126 index 0000000000..e69de29bb2 127 [EOF] 128 "); 129 insta::assert_snapshot!(get_evolog(&work_dir, "description(1)"), @r" 130 ○ kkmpptxz d366d92c 1 131 ├─╮ 132 │ ○ yqosqzyt hidden c506fbc7 (no description set) 133 │ ○ yqosqzyt hidden 277bed24 (empty) (no description set) 134 ○ kkmpptxz hidden d0f1e8dd 1 135 ├─╮ 136 │ ○ mzvwutvl hidden 8935ee61 (no description set) 137 │ ○ mzvwutvl hidden 2bc3d2ce (empty) (no description set) 138 ○ kkmpptxz hidden ee76d790 1 139 ○ kkmpptxz hidden 677e62d5 (empty) 1 140 [EOF] 141 "); 142 insta::assert_snapshot!(get_evolog(&work_dir, "description(2)"), @r" 143 ○ zsuskuln 6e2c4777 2 144 ├─╮ 145 │ ○ vruxwmqv hidden 7b1da5cd (no description set) 146 │ ○ vruxwmqv hidden 32eb72fe (empty) (no description set) 147 ○ zsuskuln hidden 5bf0bc06 2 148 ○ zsuskuln hidden 3027ca7a 2 149 ├─╮ 150 │ ○ mzvwutvl hidden 8935ee61 (no description set) 151 │ ○ mzvwutvl hidden 2bc3d2ce (empty) (no description set) 152 ○ zsuskuln hidden cca09b4d 2 153 ○ zsuskuln hidden 7b092471 (empty) 2 154 [EOF] 155 "); 156} 157 158#[test] 159fn test_absorb_replace_single_line_hunk() { 160 let test_env = TestEnvironment::default(); 161 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 162 let work_dir = test_env.work_dir("repo"); 163 164 work_dir.run_jj(["describe", "-m1"]).success(); 165 work_dir.write_file("file1", "1a\n"); 166 167 work_dir.run_jj(["new", "-m2"]).success(); 168 work_dir.write_file("file1", "2a\n1a\n2b\n"); 169 170 // Replace single-line hunk, which produces a conflict right now. If our 171 // merge logic were based on interleaved delta, the hunk would be applied 172 // cleanly. 173 work_dir.run_jj(["new"]).success(); 174 work_dir.write_file("file1", "2a\n1A\n2b\n"); 175 let output = work_dir.run_jj(["absorb"]); 176 insta::assert_snapshot!(output, @r" 177 ------- stderr ------- 178 Absorbed changes into 1 revisions: 179 qpvuntsm 7e885236 (conflict) 1 180 Rebased 1 descendant commits. 181 Working copy (@) now at: mzvwutvl e9c3b95b (empty) (no description set) 182 Parent commit (@-) : kkmpptxz 7c36845c 2 183 New conflicts appeared in 1 commits: 184 qpvuntsm 7e885236 (conflict) 1 185 Hint: To resolve the conflicts, start by updating to it: 186 jj new qpvuntsm 187 Then use `jj resolve`, or edit the conflict markers in the file directly. 188 Once the conflicts are resolved, you may want to inspect the result with `jj diff`. 189 Then run `jj squash` to move the resolution into the conflicted commit. 190 [EOF] 191 "); 192 193 insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r" 194 @ mzvwutvl e9c3b95b (empty) (no description set) 195 ○ kkmpptxz 7c36845c 2 196 │ diff --git a/file1 b/file1 197 │ index 0000000000..2f87e8e465 100644 198 │ --- a/file1 199 │ +++ b/file1 200 │ @@ -1,10 +1,3 @@ 201 │ -<<<<<<< Conflict 1 of 1 202 │ -%%%%%%% Changes from base to side #1 203 │ --2a 204 │ - 1a 205 │ --2b 206 │ -+++++++ Contents of side #2 207 │ 2a 208 │ 1A 209 │ 2b 210 │ ->>>>>>> Conflict 1 of 1 ends 211 × qpvuntsm 7e885236 (conflict) 1 212 │ diff --git a/file1 b/file1 213 ~ new file mode 100644 214 index 0000000000..0000000000 215 --- /dev/null 216 +++ b/file1 217 @@ -0,0 +1,10 @@ 218 +<<<<<<< Conflict 1 of 1 219 +%%%%%%% Changes from base to side #1 220 +-2a 221 + 1a 222 +-2b 223 ++++++++ Contents of side #2 224 +2a 225 +1A 226 +2b 227 +>>>>>>> Conflict 1 of 1 ends 228 [EOF] 229 "); 230} 231 232#[test] 233fn test_absorb_merge() { 234 let test_env = TestEnvironment::default(); 235 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 236 let work_dir = test_env.work_dir("repo"); 237 238 work_dir.run_jj(["describe", "-m0"]).success(); 239 work_dir.write_file("file1", "0a\n"); 240 241 work_dir.run_jj(["new", "-m1"]).success(); 242 work_dir.write_file("file1", "1a\n1b\n0a\n"); 243 244 work_dir.run_jj(["new", "-m2", "description(0)"]).success(); 245 work_dir.write_file("file1", "0a\n2a\n2b\n"); 246 247 let output = work_dir.run_jj(["new", "-m3", "description(1)", "description(2)"]); 248 insta::assert_snapshot!(output, @r" 249 ------- stderr ------- 250 Working copy (@) now at: mzvwutvl 08898161 (empty) 3 251 Parent commit (@-) : kkmpptxz 7e9df299 1 252 Parent commit (@-) : zsuskuln baf056cf 2 253 Added 0 files, modified 1 files, removed 0 files 254 [EOF] 255 "); 256 257 // Modify first and last lines, absorb from merge 258 work_dir.write_file("file1", "1A\n1b\n0a\n2a\n2B\n"); 259 let output = work_dir.run_jj(["absorb"]); 260 insta::assert_snapshot!(output, @r" 261 ------- stderr ------- 262 Absorbed changes into 2 revisions: 263 zsuskuln 71d1ee56 2 264 kkmpptxz 4d379399 1 265 Rebased 1 descendant commits. 266 Working copy (@) now at: mzvwutvl 9db19b54 (empty) 3 267 Parent commit (@-) : kkmpptxz 4d379399 1 268 Parent commit (@-) : zsuskuln 71d1ee56 2 269 [EOF] 270 "); 271 272 // Add hunk to merge revision 273 work_dir.write_file("file2", "3a\n"); 274 275 // Absorb into merge 276 work_dir.run_jj(["new"]).success(); 277 work_dir.write_file("file2", "3A\n"); 278 let output = work_dir.run_jj(["absorb"]); 279 insta::assert_snapshot!(output, @r" 280 ------- stderr ------- 281 Absorbed changes into 1 revisions: 282 mzvwutvl e93c0210 3 283 Working copy (@) now at: vruxwmqv 1b10dfa4 (empty) (no description set) 284 Parent commit (@-) : mzvwutvl e93c0210 3 285 [EOF] 286 "); 287 288 insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r" 289 @ vruxwmqv 1b10dfa4 (empty) (no description set) 290 ○ mzvwutvl e93c0210 3 291 ├─╮ diff --git a/file2 b/file2 292 │ │ new file mode 100644 293 │ │ index 0000000000..44442d2d7b 294 │ │ --- /dev/null 295 │ │ +++ b/file2 296 │ │ @@ -0,0 +1,1 @@ 297 │ │ +3A 298 │ ○ zsuskuln 71d1ee56 2 299 │ │ diff --git a/file1 b/file1 300 │ │ index eb6e8821f1..4907935b9f 100644 301 │ │ --- a/file1 302 │ │ +++ b/file1 303 │ │ @@ -1,1 +1,3 @@ 304 │ │ 0a 305 │ │ +2a 306 │ │ +2B 307 ○ │ kkmpptxz 4d379399 1 308 ├─╯ diff --git a/file1 b/file1 309 │ index eb6e8821f1..902dd8ef13 100644 310 │ --- a/file1 311 │ +++ b/file1 312 │ @@ -1,1 +1,3 @@ 313 │ +1A 314 │ +1b 315 │ 0a 316 ○ qpvuntsm 3777b700 0 317 │ diff --git a/file1 b/file1 318 ~ new file mode 100644 319 index 0000000000..eb6e8821f1 320 --- /dev/null 321 +++ b/file1 322 @@ -0,0 +1,1 @@ 323 +0a 324 [EOF] 325 "); 326} 327 328#[test] 329fn test_absorb_discardable_merge_with_descendant() { 330 let test_env = TestEnvironment::default(); 331 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 332 let work_dir = test_env.work_dir("repo"); 333 334 work_dir.run_jj(["describe", "-m0"]).success(); 335 work_dir.write_file("file1", "0a\n"); 336 337 work_dir.run_jj(["new", "-m1"]).success(); 338 work_dir.write_file("file1", "1a\n1b\n0a\n"); 339 340 work_dir.run_jj(["new", "-m2", "description(0)"]).success(); 341 work_dir.write_file("file1", "0a\n2a\n2b\n"); 342 343 let output = work_dir.run_jj(["new", "description(1)", "description(2)"]); 344 insta::assert_snapshot!(output, @r" 345 ------- stderr ------- 346 Working copy (@) now at: mzvwutvl f59b2364 (empty) (no description set) 347 Parent commit (@-) : kkmpptxz 7e9df299 1 348 Parent commit (@-) : zsuskuln baf056cf 2 349 Added 0 files, modified 1 files, removed 0 files 350 [EOF] 351 "); 352 353 // Modify first and last lines in the merge commit 354 work_dir.write_file("file1", "1A\n1b\n0a\n2a\n2B\n"); 355 // Add new commit on top 356 work_dir.run_jj(["new", "-m3"]).success(); 357 work_dir.write_file("file2", "3a\n"); 358 // Then absorb the merge commit 359 let output = work_dir.run_jj(["absorb", "--from=@-"]); 360 insta::assert_snapshot!(output, @r" 361 ------- stderr ------- 362 Absorbed changes into 2 revisions: 363 zsuskuln 02668cf6 2 364 kkmpptxz fcabe394 1 365 Rebased 1 descendant commits. 366 Working copy (@) now at: royxmykx f04f1247 3 367 Parent commit (@-) : kkmpptxz fcabe394 1 368 Parent commit (@-) : zsuskuln 02668cf6 2 369 [EOF] 370 "); 371 372 insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r" 373 @ royxmykx f04f1247 3 374 ├─╮ diff --git a/file2 b/file2 375 │ │ new file mode 100644 376 │ │ index 0000000000..31cd755d20 377 │ │ --- /dev/null 378 │ │ +++ b/file2 379 │ │ @@ -0,0 +1,1 @@ 380 │ │ +3a 381 │ ○ zsuskuln 02668cf6 2 382 │ │ diff --git a/file1 b/file1 383 │ │ index eb6e8821f1..4907935b9f 100644 384 │ │ --- a/file1 385 │ │ +++ b/file1 386 │ │ @@ -1,1 +1,3 @@ 387 │ │ 0a 388 │ │ +2a 389 │ │ +2B 390 ○ │ kkmpptxz fcabe394 1 391 ├─╯ diff --git a/file1 b/file1 392 │ index eb6e8821f1..902dd8ef13 100644 393 │ --- a/file1 394 │ +++ b/file1 395 │ @@ -1,1 +1,3 @@ 396 │ +1A 397 │ +1b 398 │ 0a 399 ○ qpvuntsm 3777b700 0 400 │ diff --git a/file1 b/file1 401 ~ new file mode 100644 402 index 0000000000..eb6e8821f1 403 --- /dev/null 404 +++ b/file1 405 @@ -0,0 +1,1 @@ 406 +0a 407 [EOF] 408 "); 409} 410 411#[test] 412fn test_absorb_conflict() { 413 let test_env = TestEnvironment::default(); 414 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 415 let work_dir = test_env.work_dir("repo"); 416 417 work_dir.run_jj(["describe", "-m1"]).success(); 418 work_dir.write_file("file1", "1a\n1b\n"); 419 420 work_dir.run_jj(["new", "root()"]).success(); 421 work_dir.write_file("file1", "2a\n2b\n"); 422 let output = work_dir.run_jj(["rebase", "-r@", "-ddescription(1)"]); 423 insta::assert_snapshot!(output, @r" 424 ------- stderr ------- 425 Rebased 1 commits onto destination 426 Working copy (@) now at: kkmpptxz 74405a07 (conflict) (no description set) 427 Parent commit (@-) : qpvuntsm 3619e4e5 1 428 Added 0 files, modified 1 files, removed 0 files 429 Warning: There are unresolved conflicts at these paths: 430 file1 2-sided conflict 431 New conflicts appeared in 1 commits: 432 kkmpptxz 74405a07 (conflict) (no description set) 433 Hint: To resolve the conflicts, start by updating to it: 434 jj new kkmpptxz 435 Then use `jj resolve`, or edit the conflict markers in the file directly. 436 Once the conflicts are resolved, you may want to inspect the result with `jj diff`. 437 Then run `jj squash` to move the resolution into the conflicted commit. 438 [EOF] 439 "); 440 441 let conflict_content = work_dir.read_file("file1"); 442 insta::assert_snapshot!(conflict_content, @r" 443 <<<<<<< Conflict 1 of 1 444 %%%%%%% Changes from base to side #1 445 +1a 446 +1b 447 +++++++ Contents of side #2 448 2a 449 2b 450 >>>>>>> Conflict 1 of 1 ends 451 "); 452 453 // Cannot absorb from conflict 454 let output = work_dir.run_jj(["absorb"]); 455 insta::assert_snapshot!(output, @r" 456 ------- stderr ------- 457 Warning: Skipping file1: Is a conflict 458 Nothing changed. 459 [EOF] 460 "); 461 462 // Cannot absorb from resolved conflict 463 work_dir.run_jj(["new"]).success(); 464 work_dir.write_file("file1", "1A\n1b\n2a\n2B\n"); 465 let output = work_dir.run_jj(["absorb"]); 466 insta::assert_snapshot!(output, @r" 467 ------- stderr ------- 468 Warning: Skipping file1: Is a conflict 469 Nothing changed. 470 [EOF] 471 "); 472} 473 474#[test] 475fn test_absorb_deleted_file() { 476 let test_env = TestEnvironment::default(); 477 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 478 let work_dir = test_env.work_dir("repo"); 479 480 work_dir.run_jj(["describe", "-m1"]).success(); 481 work_dir.write_file("file1", "1a\n"); 482 483 work_dir.run_jj(["new"]).success(); 484 work_dir.remove_file("file1"); 485 486 let output = work_dir.run_jj(["absorb"]); 487 insta::assert_snapshot!(output, @r" 488 ------- stderr ------- 489 Warning: Skipping file1: Deleted file 490 Nothing changed. 491 [EOF] 492 "); 493} 494 495#[test] 496fn test_absorb_file_mode() { 497 let test_env = TestEnvironment::default(); 498 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 499 let work_dir = test_env.work_dir("repo"); 500 501 work_dir.run_jj(["describe", "-m1"]).success(); 502 work_dir.write_file("file1", "1a\n"); 503 work_dir.run_jj(["file", "chmod", "x", "file1"]).success(); 504 505 // Modify content and mode 506 work_dir.run_jj(["new"]).success(); 507 work_dir.write_file("file1", "1A\n"); 508 work_dir.run_jj(["file", "chmod", "n", "file1"]).success(); 509 510 // Mode change shouldn't be absorbed 511 let output = work_dir.run_jj(["absorb"]); 512 insta::assert_snapshot!(output, @r" 513 ------- stderr ------- 514 Absorbed changes into 1 revisions: 515 qpvuntsm 991365da 1 516 Rebased 1 descendant commits. 517 Working copy (@) now at: zsuskuln 77de368e (no description set) 518 Parent commit (@-) : qpvuntsm 991365da 1 519 Remaining changes: 520 M file1 521 [EOF] 522 "); 523 524 insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r" 525 @ zsuskuln 77de368e (no description set) 526 │ diff --git a/file1 b/file1 527 │ old mode 100755 528 │ new mode 100644 529 ○ qpvuntsm 991365da 1 530 │ diff --git a/file1 b/file1 531 ~ new file mode 100755 532 index 0000000000..268de3f3ec 533 --- /dev/null 534 +++ b/file1 535 @@ -0,0 +1,1 @@ 536 +1A 537 [EOF] 538 "); 539} 540 541#[test] 542fn test_absorb_from_into() { 543 let test_env = TestEnvironment::default(); 544 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 545 let work_dir = test_env.work_dir("repo"); 546 547 work_dir.run_jj(["new", "-m1"]).success(); 548 work_dir.write_file("file1", "1a\n1b\n1c\n"); 549 550 work_dir.run_jj(["new", "-m2"]).success(); 551 work_dir.write_file("file1", "1a\n2a\n1b\n1c\n2b\n"); 552 553 // Line "X" and "Z" have unambiguous adjacent line within the destinations 554 // range. Line "Y" doesn't have such line. 555 work_dir.run_jj(["new"]).success(); 556 work_dir.write_file("file1", "1a\nX\n2a\n1b\nY\n1c\n2b\nZ\n"); 557 let output = work_dir.run_jj(["absorb", "--into=@-"]); 558 insta::assert_snapshot!(output, @r" 559 ------- stderr ------- 560 Absorbed changes into 1 revisions: 561 kkmpptxz 91df4543 2 562 Rebased 1 descendant commits. 563 Working copy (@) now at: zsuskuln d5424357 (no description set) 564 Parent commit (@-) : kkmpptxz 91df4543 2 565 Remaining changes: 566 M file1 567 [EOF] 568 "); 569 570 insta::assert_snapshot!(get_diffs(&work_dir, "@-::"), @r" 571 @ zsuskuln d5424357 (no description set) 572 │ diff --git a/file1 b/file1 573 │ index faf62af049..c2d0b12547 100644 574 │ --- a/file1 575 │ +++ b/file1 576 │ @@ -2,6 +2,7 @@ 577 │ X 578 │ 2a 579 │ 1b 580 │ +Y 581 │ 1c 582 │ 2b 583 │ Z 584 ○ kkmpptxz 91df4543 2 585 │ diff --git a/file1 b/file1 586 ~ index 352e9b3794..faf62af049 100644 587 --- a/file1 588 +++ b/file1 589 @@ -1,3 +1,7 @@ 590 1a 591 +X 592 +2a 593 1b 594 1c 595 +2b 596 +Z 597 [EOF] 598 "); 599 600 // Absorb all lines from the working-copy parent. An empty commit won't be 601 // discarded because "absorb" isn't a command to squash commit descriptions. 602 let output = work_dir.run_jj(["absorb", "--from=@-"]); 603 insta::assert_snapshot!(output, @r" 604 ------- stderr ------- 605 Absorbed changes into 1 revisions: 606 rlvkpnrz 3a5fd02e 1 607 Rebased 2 descendant commits. 608 Working copy (@) now at: zsuskuln 53ce490b (no description set) 609 Parent commit (@-) : kkmpptxz c94cd773 (empty) 2 610 [EOF] 611 "); 612 613 insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r" 614 @ zsuskuln 53ce490b (no description set) 615 │ diff --git a/file1 b/file1 616 │ index faf62af049..c2d0b12547 100644 617 │ --- a/file1 618 │ +++ b/file1 619 │ @@ -2,6 +2,7 @@ 620 │ X 621 │ 2a 622 │ 1b 623 │ +Y 624 │ 1c 625 │ 2b 626 │ Z 627 ○ kkmpptxz c94cd773 (empty) 2 628 ○ rlvkpnrz 3a5fd02e 1 629 │ diff --git a/file1 b/file1 630 │ new file mode 100644 631 │ index 0000000000..faf62af049 632 │ --- /dev/null 633 │ +++ b/file1 634 │ @@ -0,0 +1,7 @@ 635 │ +1a 636 │ +X 637 │ +2a 638 │ +1b 639 │ +1c 640 │ +2b 641 │ +Z 642 ○ qpvuntsm 230dd059 (empty) (no description set) 643644 ~ 645 [EOF] 646 "); 647} 648 649#[test] 650fn test_absorb_paths() { 651 let test_env = TestEnvironment::default(); 652 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 653 let work_dir = test_env.work_dir("repo"); 654 655 work_dir.run_jj(["describe", "-m1"]).success(); 656 work_dir.write_file("file1", "1a\n"); 657 work_dir.write_file("file2", "1a\n"); 658 659 // Modify both files 660 work_dir.run_jj(["new"]).success(); 661 work_dir.write_file("file1", "1A\n"); 662 work_dir.write_file("file2", "1A\n"); 663 664 let output = work_dir.run_jj(["absorb", "unknown"]); 665 insta::assert_snapshot!(output, @r" 666 ------- stderr ------- 667 Nothing changed. 668 [EOF] 669 "); 670 671 let output = work_dir.run_jj(["absorb", "file1"]); 672 insta::assert_snapshot!(output, @r" 673 ------- stderr ------- 674 Absorbed changes into 1 revisions: 675 qpvuntsm ae044adb 1 676 Rebased 1 descendant commits. 677 Working copy (@) now at: kkmpptxz c6f31836 (no description set) 678 Parent commit (@-) : qpvuntsm ae044adb 1 679 Remaining changes: 680 M file2 681 [EOF] 682 "); 683 684 insta::assert_snapshot!(get_diffs(&work_dir, "mutable()"), @r" 685 @ kkmpptxz c6f31836 (no description set) 686 │ diff --git a/file2 b/file2 687 │ index a8994dc188..268de3f3ec 100644 688 │ --- a/file2 689 │ +++ b/file2 690 │ @@ -1,1 +1,1 @@ 691 │ -1a 692 │ +1A 693 ○ qpvuntsm ae044adb 1 694 │ diff --git a/file1 b/file1 695 ~ new file mode 100644 696 index 0000000000..268de3f3ec 697 --- /dev/null 698 +++ b/file1 699 @@ -0,0 +1,1 @@ 700 +1A 701 diff --git a/file2 b/file2 702 new file mode 100644 703 index 0000000000..a8994dc188 704 --- /dev/null 705 +++ b/file2 706 @@ -0,0 +1,1 @@ 707 +1a 708 [EOF] 709 "); 710} 711 712#[test] 713fn test_absorb_immutable() { 714 let test_env = TestEnvironment::default(); 715 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 716 let work_dir = test_env.work_dir("repo"); 717 test_env.add_config("revset-aliases.'immutable_heads()' = 'present(main)'"); 718 719 work_dir.run_jj(["describe", "-m1"]).success(); 720 work_dir.write_file("file1", "1a\n1b\n"); 721 722 work_dir.run_jj(["new", "-m2"]).success(); 723 work_dir 724 .run_jj(["bookmark", "set", "-r@-", "main"]) 725 .success(); 726 work_dir.write_file("file1", "1a\n1b\n2a\n2b\n"); 727 728 work_dir.run_jj(["new"]).success(); 729 work_dir.write_file("file1", "1A\n1b\n2a\n2B\n"); 730 731 // Immutable revisions are excluded by default 732 let output = work_dir.run_jj(["absorb"]); 733 insta::assert_snapshot!(output, @r" 734 ------- stderr ------- 735 Absorbed changes into 1 revisions: 736 kkmpptxz d80e3c2a 2 737 Rebased 1 descendant commits. 738 Working copy (@) now at: mzvwutvl 3021153d (no description set) 739 Parent commit (@-) : kkmpptxz d80e3c2a 2 740 Remaining changes: 741 M file1 742 [EOF] 743 "); 744 745 // Immutable revisions shouldn't be rewritten 746 let output = work_dir.run_jj(["absorb", "--into=all()"]); 747 insta::assert_snapshot!(output, @r#" 748 ------- stderr ------- 749 Error: Commit 3619e4e52fce is immutable 750 Hint: Could not modify commit: qpvuntsm 3619e4e5 main | 1 751 Hint: Immutable commits are used to protect shared history. 752 Hint: For more information, see: 753 - https://jj-vcs.github.io/jj/latest/config/#set-of-immutable-commits 754 - `jj help -k config`, "Set of immutable commits" 755 Hint: This operation would rewrite 1 immutable commits. 756 [EOF] 757 [exit status: 1] 758 "#); 759 760 insta::assert_snapshot!(get_diffs(&work_dir, ".."), @r" 761 @ mzvwutvl 3021153d (no description set) 762 │ diff --git a/file1 b/file1 763 │ index 75e4047831..428796ca20 100644 764 │ --- a/file1 765 │ +++ b/file1 766 │ @@ -1,4 +1,4 @@ 767 │ -1a 768 │ +1A 769 │ 1b 770 │ 2a 771 │ 2B 772 ○ kkmpptxz d80e3c2a 2 773 │ diff --git a/file1 b/file1 774 │ index 8c5268f893..75e4047831 100644 775 │ --- a/file1 776 │ +++ b/file1 777 │ @@ -1,2 +1,4 @@ 778 │ 1a 779 │ 1b 780 │ +2a 781 │ +2B 782 ◆ qpvuntsm 3619e4e5 1 783 │ diff --git a/file1 b/file1 784 ~ new file mode 100644 785 index 0000000000..8c5268f893 786 --- /dev/null 787 +++ b/file1 788 @@ -0,0 +1,2 @@ 789 +1a 790 +1b 791 [EOF] 792 "); 793} 794 795#[must_use] 796fn get_diffs(work_dir: &TestWorkDir, revision: &str) -> CommandOutput { 797 let template = r#"format_commit_summary_with_refs(self, "") ++ "\n""#; 798 work_dir.run_jj(["log", "-r", revision, "-T", template, "--git"]) 799} 800 801#[must_use] 802fn get_evolog(work_dir: &TestWorkDir, revision: &str) -> CommandOutput { 803 let template = r#"format_commit_summary_with_refs(self, "") ++ "\n""#; 804 work_dir.run_jj(["evolog", "-r", revision, "-T", template]) 805}