just playing with tangled
at ig/vimdiffwarn 2442 lines 80 kB view raw
1// Copyright 2023 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; 16use crate::common::CommandOutput; 17use crate::common::TestEnvironment; 18use crate::common::TestWorkDir; 19 20#[test] 21fn test_duplicate() { 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 create_commit(&work_dir, "a", &[]); 27 create_commit(&work_dir, "b", &[]); 28 create_commit(&work_dir, "c", &["a", "b"]); 29 // Test the setup 30 insta::assert_snapshot!(get_log_output(&work_dir), @r" 31 @ 17a00fc21654 c 32 ├─╮ 33 │ ○ d370aee184ba b 34 ○ │ 2443ea76b0b1 a 35 ├─╯ 36 ◆ 000000000000 37 [EOF] 38 "); 39 40 let output = work_dir.run_jj(["duplicate", "all()"]); 41 insta::assert_snapshot!(output, @r" 42 ------- stderr ------- 43 Error: Cannot duplicate the root commit 44 [EOF] 45 [exit status: 1] 46 "); 47 48 let output = work_dir.run_jj(["duplicate", "none()"]); 49 insta::assert_snapshot!(output, @r" 50 ------- stderr ------- 51 No revisions to duplicate. 52 [EOF] 53 "); 54 55 let output = work_dir.run_jj(["duplicate", "a"]); 56 insta::assert_snapshot!(output, @r" 57 ------- stderr ------- 58 Duplicated 2443ea76b0b1 as kpqxywon f5b1e687 a 59 [EOF] 60 "); 61 insta::assert_snapshot!(get_log_output(&work_dir), @r" 62 @ 17a00fc21654 c 63 ├─╮ 64 │ ○ d370aee184ba b 65 ○ │ 2443ea76b0b1 a 66 ├─╯ 67 │ ○ f5b1e68729d6 a 68 ├─╯ 69 ◆ 000000000000 70 [EOF] 71 "); 72 73 let output = work_dir.run_jj(["undo"]); 74 insta::assert_snapshot!(output, @r" 75 ------- stderr ------- 76 Undid operation: 6eead29c6998 (2001-02-03 08:05:17) duplicate 1 commit(s) 77 [EOF] 78 "); 79 let output = work_dir.run_jj(["duplicate" /* duplicates `c` */]); 80 insta::assert_snapshot!(output, @r" 81 ------- stderr ------- 82 Duplicated 17a00fc21654 as lylxulpl ef3b0f3d c 83 [EOF] 84 "); 85 insta::assert_snapshot!(get_log_output(&work_dir), @r" 86 @ 17a00fc21654 c 87 ├─╮ 88 │ │ ○ ef3b0f3d1046 c 89 ╭─┬─╯ 90 │ ○ d370aee184ba b 91 ○ │ 2443ea76b0b1 a 92 ├─╯ 93 ◆ 000000000000 94 [EOF] 95 "); 96} 97 98#[test] 99fn test_duplicate_many() { 100 let test_env = TestEnvironment::default(); 101 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 102 let work_dir = test_env.work_dir("repo"); 103 104 create_commit(&work_dir, "a", &[]); 105 create_commit(&work_dir, "b", &["a"]); 106 create_commit(&work_dir, "c", &["a"]); 107 create_commit(&work_dir, "d", &["c"]); 108 create_commit(&work_dir, "e", &["b", "d"]); 109 // Test the setup 110 insta::assert_snapshot!(get_log_output(&work_dir), @r" 111 @ 921dde6e55c0 e 112 ├─╮ 113 │ ○ ebd06dba20ec d 114 │ ○ c0cb3a0b73e7 c 115 ○ │ 1394f625cbbd b 116 ├─╯ 117 ○ 2443ea76b0b1 a 118 ◆ 000000000000 119 [EOF] 120 "); 121 122 let output = work_dir.run_jj(["duplicate", "b::"]); 123 insta::assert_snapshot!(output, @r" 124 ------- stderr ------- 125 Duplicated 1394f625cbbd as wqnwkozp 3b74d969 b 126 Duplicated 921dde6e55c0 as mouksmqu 8348ddce e 127 [EOF] 128 "); 129 insta::assert_snapshot!(get_log_output(&work_dir), @r" 130 @ 921dde6e55c0 e 131 ├─╮ 132 ○ │ 1394f625cbbd b 133 │ │ ○ 8348ddcec733 e 134 │ ╭─┤ 135 │ ○ │ ebd06dba20ec d 136 │ ○ │ c0cb3a0b73e7 c 137 ├─╯ │ 138 │ ○ 3b74d9691015 b 139 ├───╯ 140 ○ 2443ea76b0b1 a 141 ◆ 000000000000 142 [EOF] 143 "); 144 145 // Try specifying the same commit twice directly 146 work_dir.run_jj(["undo"]).success(); 147 let output = work_dir.run_jj(["duplicate", "b", "b"]); 148 insta::assert_snapshot!(output, @r" 149 ------- stderr ------- 150 Duplicated 1394f625cbbd as nkmrtpmo 0276d3d7 b 151 [EOF] 152 "); 153 insta::assert_snapshot!(get_log_output(&work_dir), @r" 154 @ 921dde6e55c0 e 155 ├─╮ 156 │ ○ ebd06dba20ec d 157 │ ○ c0cb3a0b73e7 c 158 ○ │ 1394f625cbbd b 159 ├─╯ 160 │ ○ 0276d3d7c24d b 161 ├─╯ 162 ○ 2443ea76b0b1 a 163 ◆ 000000000000 164 [EOF] 165 "); 166 167 // Try specifying the same commit twice indirectly 168 work_dir.run_jj(["undo"]).success(); 169 let output = work_dir.run_jj(["duplicate", "b::", "d::"]); 170 insta::assert_snapshot!(output, @r" 171 ------- stderr ------- 172 Duplicated 1394f625cbbd as xtnwkqum fa167d18 b 173 Duplicated ebd06dba20ec as pqrnrkux 2181781b d 174 Duplicated 921dde6e55c0 as ztxkyksq 0f7430f2 e 175 [EOF] 176 "); 177 insta::assert_snapshot!(get_log_output(&work_dir), @r" 178 @ 921dde6e55c0 e 179 ├─╮ 180 │ ○ ebd06dba20ec d 181 ○ │ 1394f625cbbd b 182 │ │ ○ 0f7430f2727a e 183 │ │ ├─╮ 184 │ │ │ ○ 2181781b4f81 d 185 │ ├───╯ 186 │ ○ │ c0cb3a0b73e7 c 187 ├─╯ │ 188 │ ○ fa167d18a83a b 189 ├───╯ 190 ○ 2443ea76b0b1 a 191 ◆ 000000000000 192 [EOF] 193 "); 194 195 work_dir.run_jj(["undo"]).success(); 196 // Reminder of the setup 197 insta::assert_snapshot!(get_log_output(&work_dir), @r" 198 @ 921dde6e55c0 e 199 ├─╮ 200 │ ○ ebd06dba20ec d 201 │ ○ c0cb3a0b73e7 c 202 ○ │ 1394f625cbbd b 203 ├─╯ 204 ○ 2443ea76b0b1 a 205 ◆ 000000000000 206 [EOF] 207 "); 208 let output = work_dir.run_jj(["duplicate", "d::", "a"]); 209 insta::assert_snapshot!(output, @r" 210 ------- stderr ------- 211 Duplicated 2443ea76b0b1 as nlrtlrxv c6f7f8c4 a 212 Duplicated ebd06dba20ec as plymsszl d94e4c55 d 213 Duplicated 921dde6e55c0 as urrlptpw 9bd4389f e 214 [EOF] 215 "); 216 insta::assert_snapshot!(get_log_output(&work_dir), @r" 217 @ 921dde6e55c0 e 218 ├─╮ 219 │ ○ ebd06dba20ec d 220 │ │ ○ 9bd4389f5d47 e 221 ╭───┤ 222 │ │ ○ d94e4c55a68b d 223 │ ├─╯ 224 │ ○ c0cb3a0b73e7 c 225 ○ │ 1394f625cbbd b 226 ├─╯ 227 ○ 2443ea76b0b1 a 228 │ ○ c6f7f8c4512e a 229 ├─╯ 230 ◆ 000000000000 231 [EOF] 232 "); 233 234 // Check for BUG -- makes too many 'a'-s, etc. 235 work_dir.run_jj(["undo"]).success(); 236 let output = work_dir.run_jj(["duplicate", "a::"]); 237 insta::assert_snapshot!(output, @r" 238 ------- stderr ------- 239 Duplicated 2443ea76b0b1 as uuuvxpvw 0fe67a05 a 240 Duplicated 1394f625cbbd as nmpuuozl e13ac0ad b 241 Duplicated c0cb3a0b73e7 as kzpokyyw df53fa58 c 242 Duplicated ebd06dba20ec as yxrlprzz 2f2442db d 243 Duplicated 921dde6e55c0 as mvkzkxrl ee8fe64e e 244 [EOF] 245 "); 246 insta::assert_snapshot!(get_log_output(&work_dir), @r" 247 @ 921dde6e55c0 e 248 ├─╮ 249 │ ○ ebd06dba20ec d 250 │ ○ c0cb3a0b73e7 c 251 ○ │ 1394f625cbbd b 252 ├─╯ 253 ○ 2443ea76b0b1 a 254 │ ○ ee8fe64ed254 e 255 │ ├─╮ 256 │ │ ○ 2f2442db08eb d 257 │ │ ○ df53fa589286 c 258 │ ○ │ e13ac0adabdf b 259 │ ├─╯ 260 │ ○ 0fe67a05989e a 261 ├─╯ 262 ◆ 000000000000 263 [EOF] 264 "); 265} 266 267#[test] 268fn test_duplicate_destination() { 269 let test_env = TestEnvironment::default(); 270 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 271 let work_dir = test_env.work_dir("repo"); 272 273 create_commit(&work_dir, "a1", &[]); 274 create_commit(&work_dir, "a2", &["a1"]); 275 create_commit(&work_dir, "a3", &["a2"]); 276 create_commit(&work_dir, "b", &[]); 277 create_commit(&work_dir, "c", &[]); 278 create_commit(&work_dir, "d", &[]); 279 let setup_opid = work_dir.current_operation_id(); 280 281 // Test the setup 282 insta::assert_snapshot!(get_log_output(&work_dir), @r" 283 @ f7550bb42c6f d 284 │ ○ b75b7aa4b90e c 285 ├─╯ 286 │ ○ 9a27d5939bef b 287 ├─╯ 288 │ ○ 17072aa2b823 a3 289 │ ○ 47df67757a64 a2 290 │ ○ 9e85a474f005 a1 291 ├─╯ 292 ◆ 000000000000 293 [EOF] 294 "); 295 296 // Duplicate a single commit onto a single destination. 297 let output = work_dir.run_jj(["duplicate", "a1", "-d", "c"]); 298 insta::assert_snapshot!(output, @r" 299 ------- stderr ------- 300 Duplicated 9e85a474f005 as nkmrtpmo 2944a632 a1 301 [EOF] 302 "); 303 insta::assert_snapshot!(get_log_output(&work_dir), @r" 304 @ f7550bb42c6f d 305 │ ○ 2944a6324f14 a1 306 │ ○ b75b7aa4b90e c 307 ├─╯ 308 │ ○ 9a27d5939bef b 309 ├─╯ 310 │ ○ 17072aa2b823 a3 311 │ ○ 47df67757a64 a2 312 │ ○ 9e85a474f005 a1 313 ├─╯ 314 ◆ 000000000000 315 [EOF] 316 "); 317 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 318 319 // Duplicate a single commit onto multiple destinations. 320 let output = work_dir.run_jj(["duplicate", "a1", "-d", "c", "-d", "d"]); 321 insta::assert_snapshot!(output, @r" 322 ------- stderr ------- 323 Duplicated 9e85a474f005 as xtnwkqum 155f6a01 a1 324 [EOF] 325 "); 326 insta::assert_snapshot!(get_log_output(&work_dir), @r" 327 ○ 155f6a012334 a1 328 ├─╮ 329 │ @ f7550bb42c6f d 330 ○ │ b75b7aa4b90e c 331 ├─╯ 332 │ ○ 9a27d5939bef b 333 ├─╯ 334 │ ○ 17072aa2b823 a3 335 │ ○ 47df67757a64 a2 336 │ ○ 9e85a474f005 a1 337 ├─╯ 338 ◆ 000000000000 339 [EOF] 340 "); 341 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 342 343 // Duplicate a single commit onto its descendant. 344 let output = work_dir.run_jj(["duplicate", "a1", "-d", "a3"]); 345 insta::assert_snapshot!(output, @r" 346 ------- stderr ------- 347 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 348 Duplicated 9e85a474f005 as wvuyspvk 95585bb2 (empty) a1 349 [EOF] 350 "); 351 insta::assert_snapshot!(get_log_output(&work_dir), @r" 352 @ f7550bb42c6f d 353 │ ○ b75b7aa4b90e c 354 ├─╯ 355 │ ○ 9a27d5939bef b 356 ├─╯ 357 │ ○ 95585bb2fe05 a1 358 │ ○ 17072aa2b823 a3 359 │ ○ 47df67757a64 a2 360 │ ○ 9e85a474f005 a1 361 ├─╯ 362 ◆ 000000000000 363 [EOF] 364 "); 365 366 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 367 // Duplicate multiple commits without a direct ancestry relationship onto a 368 // single destination. 369 let output = work_dir.run_jj(["duplicate", "-r=a1", "-r=b", "-d", "c"]); 370 insta::assert_snapshot!(output, @r" 371 ------- stderr ------- 372 Duplicated 9e85a474f005 as xlzxqlsl da0996fd a1 373 Duplicated 9a27d5939bef as vnkwvqxw 0af91ca8 b 374 [EOF] 375 "); 376 insta::assert_snapshot!(get_log_output(&work_dir), @r" 377 @ f7550bb42c6f d 378 │ ○ 0af91ca82d9c b 379 │ │ ○ da0996fda8ce a1 380 │ ├─╯ 381 │ ○ b75b7aa4b90e c 382 ├─╯ 383 │ ○ 9a27d5939bef b 384 ├─╯ 385 │ ○ 17072aa2b823 a3 386 │ ○ 47df67757a64 a2 387 │ ○ 9e85a474f005 a1 388 ├─╯ 389 ◆ 000000000000 390 [EOF] 391 "); 392 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 393 394 // Duplicate multiple commits without a direct ancestry relationship onto 395 // multiple destinations. 396 let output = work_dir.run_jj(["duplicate", "-r=a1", "b", "-d", "c", "-d", "d"]); 397 insta::assert_snapshot!(output, @r" 398 ------- stderr ------- 399 Duplicated 9e85a474f005 as oupztwtk 2f519daa a1 400 Duplicated 9a27d5939bef as yxsqzptr c219a744 b 401 [EOF] 402 "); 403 insta::assert_snapshot!(get_log_output(&work_dir), @r" 404 ○ c219a744e19c b 405 ├─╮ 406 │ │ ○ 2f519daab24d a1 407 ╭─┬─╯ 408 │ @ f7550bb42c6f d 409 ○ │ b75b7aa4b90e c 410 ├─╯ 411 │ ○ 9a27d5939bef b 412 ├─╯ 413 │ ○ 17072aa2b823 a3 414 │ ○ 47df67757a64 a2 415 │ ○ 9e85a474f005 a1 416 ├─╯ 417 ◆ 000000000000 418 [EOF] 419 "); 420 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 421 422 // Duplicate multiple commits with an ancestry relationship onto a 423 // single destination. 424 let output = work_dir.run_jj(["duplicate", "a1", "a3", "-d", "c"]); 425 insta::assert_snapshot!(output, @r" 426 ------- stderr ------- 427 Duplicated 9e85a474f005 as wtszoswq 806f2b56 a1 428 Duplicated 17072aa2b823 as qmykwtmu 161ce874 a3 429 [EOF] 430 "); 431 insta::assert_snapshot!(get_log_output(&work_dir), @r" 432 @ f7550bb42c6f d 433 │ ○ 161ce87408d5 a3 434 │ ○ 806f2b56207d a1 435 │ ○ b75b7aa4b90e c 436 ├─╯ 437 │ ○ 9a27d5939bef b 438 ├─╯ 439 │ ○ 17072aa2b823 a3 440 │ ○ 47df67757a64 a2 441 │ ○ 9e85a474f005 a1 442 ├─╯ 443 ◆ 000000000000 444 [EOF] 445 "); 446 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 447 448 // Duplicate multiple commits with an ancestry relationship onto 449 // multiple destinations. 450 let output = work_dir.run_jj(["duplicate", "a1", "a3", "-d", "c", "-d", "d"]); 451 insta::assert_snapshot!(output, @r" 452 ------- stderr ------- 453 Duplicated 9e85a474f005 as rkoyqlrv 02cbff23 a1 454 Duplicated 17072aa2b823 as zxvrqtmq ddcfb95f a3 455 [EOF] 456 "); 457 insta::assert_snapshot!(get_log_output(&work_dir), @r" 458 ○ ddcfb95ff7d8 a3 459 ○ 02cbff23a61d a1 460 ├─╮ 461 │ @ f7550bb42c6f d 462 ○ │ b75b7aa4b90e c 463 ├─╯ 464 │ ○ 9a27d5939bef b 465 ├─╯ 466 │ ○ 17072aa2b823 a3 467 │ ○ 47df67757a64 a2 468 │ ○ 9e85a474f005 a1 469 ├─╯ 470 ◆ 000000000000 471 [EOF] 472 "); 473} 474 475#[test] 476fn test_duplicate_insert_after() { 477 let test_env = TestEnvironment::default(); 478 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 479 let work_dir = test_env.work_dir("repo"); 480 481 create_commit(&work_dir, "a1", &[]); 482 create_commit(&work_dir, "a2", &["a1"]); 483 create_commit(&work_dir, "a3", &["a2"]); 484 create_commit(&work_dir, "a4", &["a3"]); 485 create_commit(&work_dir, "b1", &[]); 486 create_commit(&work_dir, "b2", &["b1"]); 487 create_commit(&work_dir, "c1", &[]); 488 create_commit(&work_dir, "c2", &["c1"]); 489 create_commit(&work_dir, "d1", &[]); 490 create_commit(&work_dir, "d2", &["d1"]); 491 let setup_opid = work_dir.current_operation_id(); 492 493 // Test the setup 494 insta::assert_snapshot!(get_log_output(&work_dir), @r" 495 @ 0cdd923e993a d2 496 ○ 0f21c5e185c5 d1 497 │ ○ 09560d60cac4 c2 498 │ ○ b27346e9a9bd c1 499 ├─╯ 500 │ ○ 7b44470918f4 b2 501 │ ○ dcc98bc8bbea b1 502 ├─╯ 503 │ ○ 196bc1f0efc1 a4 504 │ ○ 17072aa2b823 a3 505 │ ○ 47df67757a64 a2 506 │ ○ 9e85a474f005 a1 507 ├─╯ 508 ◆ 000000000000 509 [EOF] 510 "); 511 512 // Duplicate a single commit after a single commit with no direct relationship. 513 let output = work_dir.run_jj(["duplicate", "a1", "--after", "b1"]); 514 insta::assert_snapshot!(output, @r" 515 ------- stderr ------- 516 Duplicated 9e85a474f005 as pzsxstzt b71e23da a1 517 Rebased 1 commits onto duplicated commits 518 [EOF] 519 "); 520 insta::assert_snapshot!(get_log_output(&work_dir), @r" 521 @ 0cdd923e993a d2 522 ○ 0f21c5e185c5 d1 523 │ ○ 09560d60cac4 c2 524 │ ○ b27346e9a9bd c1 525 ├─╯ 526 │ ○ af12531fa2dc b2 527 │ ○ b71e23da3559 a1 528 │ ○ dcc98bc8bbea b1 529 ├─╯ 530 │ ○ 196bc1f0efc1 a4 531 │ ○ 17072aa2b823 a3 532 │ ○ 47df67757a64 a2 533 │ ○ 9e85a474f005 a1 534 ├─╯ 535 ◆ 000000000000 536 [EOF] 537 "); 538 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 539 540 // Duplicate a single commit after a single ancestor commit. 541 let output = work_dir.run_jj(["duplicate", "a3", "--after", "a1"]); 542 insta::assert_snapshot!(output, @r" 543 ------- stderr ------- 544 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 545 Duplicated 17072aa2b823 as qmkrwlvp fd3c891b a3 546 Rebased 3 commits onto duplicated commits 547 [EOF] 548 "); 549 insta::assert_snapshot!(get_log_output(&work_dir), @r" 550 @ 0cdd923e993a d2 551 ○ 0f21c5e185c5 d1 552 │ ○ 09560d60cac4 c2 553 │ ○ b27346e9a9bd c1 554 ├─╯ 555 │ ○ 7b44470918f4 b2 556 │ ○ dcc98bc8bbea b1 557 ├─╯ 558 │ ○ 027d38df36fa a4 559 │ ○ 6cb0f5884a35 a3 560 │ ○ 80e3e40b66f0 a2 561 │ ○ fd3c891b8b97 a3 562 │ ○ 9e85a474f005 a1 563 ├─╯ 564 ◆ 000000000000 565 [EOF] 566 "); 567 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 568 569 // Duplicate a single commit after a single descendant commit. 570 let output = work_dir.run_jj(["duplicate", "a1", "--after", "a3"]); 571 insta::assert_snapshot!(output, @r" 572 ------- stderr ------- 573 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 574 Duplicated 9e85a474f005 as qwyusntz a4d0b771 (empty) a1 575 Rebased 1 commits onto duplicated commits 576 [EOF] 577 "); 578 insta::assert_snapshot!(get_log_output(&work_dir), @r" 579 @ 0cdd923e993a d2 580 ○ 0f21c5e185c5 d1 581 │ ○ 09560d60cac4 c2 582 │ ○ b27346e9a9bd c1 583 ├─╯ 584 │ ○ 7b44470918f4 b2 585 │ ○ dcc98bc8bbea b1 586 ├─╯ 587 │ ○ 9fe3808a9067 a4 588 │ ○ a4d0b7715767 a1 589 │ ○ 17072aa2b823 a3 590 │ ○ 47df67757a64 a2 591 │ ○ 9e85a474f005 a1 592 ├─╯ 593 ◆ 000000000000 594 [EOF] 595 "); 596 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 597 598 // Duplicate a single commit after multiple commits with no direct 599 // relationship. 600 let output = work_dir.run_jj(["duplicate", "a1", "--after", "b1", "--after", "c1"]); 601 insta::assert_snapshot!(output, @r" 602 ------- stderr ------- 603 Duplicated 9e85a474f005 as soqnvnyz 3449bde2 a1 604 Rebased 2 commits onto duplicated commits 605 [EOF] 606 "); 607 insta::assert_snapshot!(get_log_output(&work_dir), @r" 608 @ 0cdd923e993a d2 609 ○ 0f21c5e185c5 d1 610 │ ○ c997a412ac93 c2 611 │ │ ○ e570747744ed b2 612 │ ├─╯ 613 │ ○ 3449bde20037 a1 614 │ ├─╮ 615 │ │ ○ b27346e9a9bd c1 616 ├───╯ 617 │ ○ dcc98bc8bbea b1 618 ├─╯ 619 │ ○ 196bc1f0efc1 a4 620 │ ○ 17072aa2b823 a3 621 │ ○ 47df67757a64 a2 622 │ ○ 9e85a474f005 a1 623 ├─╯ 624 ◆ 000000000000 625 [EOF] 626 "); 627 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 628 629 // Duplicate a single commit after multiple commits including an ancestor. 630 let output = work_dir.run_jj(["duplicate", "a3", "--after", "a2", "--after", "b2"]); 631 insta::assert_snapshot!(output, @r" 632 ------- stderr ------- 633 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 634 Duplicated 17072aa2b823 as nsrwusvy 48764702 a3 635 Rebased 2 commits onto duplicated commits 636 [EOF] 637 "); 638 insta::assert_snapshot!(get_log_output(&work_dir), @r" 639 @ 0cdd923e993a d2 640 ○ 0f21c5e185c5 d1 641 │ ○ 09560d60cac4 c2 642 │ ○ b27346e9a9bd c1 643 ├─╯ 644 │ ○ aead471d6dc8 a4 645 │ ○ 07fb2a10b5de a3 646 │ ○ 48764702c97c a3 647 │ ├─╮ 648 │ │ ○ 7b44470918f4 b2 649 │ │ ○ dcc98bc8bbea b1 650 ├───╯ 651 │ ○ 47df67757a64 a2 652 │ ○ 9e85a474f005 a1 653 ├─╯ 654 ◆ 000000000000 655 [EOF] 656 "); 657 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 658 659 // Duplicate a single commit after multiple commits including a descendant. 660 let output = work_dir.run_jj(["duplicate", "a1", "--after", "a3", "--after", "b2"]); 661 insta::assert_snapshot!(output, @r" 662 ------- stderr ------- 663 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 664 Duplicated 9e85a474f005 as xpnwykqz 43bcb4dc (empty) a1 665 Rebased 1 commits onto duplicated commits 666 [EOF] 667 "); 668 insta::assert_snapshot!(get_log_output(&work_dir), @r" 669 @ 0cdd923e993a d2 670 ○ 0f21c5e185c5 d1 671 │ ○ 09560d60cac4 c2 672 │ ○ b27346e9a9bd c1 673 ├─╯ 674 │ ○ 92782f7d24fe a4 675 │ ○ 43bcb4dc97f4 a1 676 │ ├─╮ 677 │ │ ○ 7b44470918f4 b2 678 │ │ ○ dcc98bc8bbea b1 679 ├───╯ 680 │ ○ 17072aa2b823 a3 681 │ ○ 47df67757a64 a2 682 │ ○ 9e85a474f005 a1 683 ├─╯ 684 ◆ 000000000000 685 [EOF] 686 "); 687 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 688 689 // Duplicate multiple commits without a direct ancestry relationship after a 690 // single commit without a direct relationship. 691 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--after", "c1"]); 692 insta::assert_snapshot!(output, @r" 693 ------- stderr ------- 694 Duplicated 9e85a474f005 as sryyqqkq 44f57f24 a1 695 Duplicated dcc98bc8bbea as pxnqtknr bcee4b60 b1 696 Rebased 1 commits onto duplicated commits 697 [EOF] 698 "); 699 insta::assert_snapshot!(get_log_output(&work_dir), @r" 700 @ 0cdd923e993a d2 701 ○ 0f21c5e185c5 d1 702 │ ○ 215600d39fed c2 703 │ ├─╮ 704 │ │ ○ bcee4b6058e4 b1 705 │ ○ │ 44f57f247bf2 a1 706 │ ├─╯ 707 │ ○ b27346e9a9bd c1 708 ├─╯ 709 │ ○ 7b44470918f4 b2 710 │ ○ dcc98bc8bbea b1 711 ├─╯ 712 │ ○ 196bc1f0efc1 a4 713 │ ○ 17072aa2b823 a3 714 │ ○ 47df67757a64 a2 715 │ ○ 9e85a474f005 a1 716 ├─╯ 717 ◆ 000000000000 718 [EOF] 719 "); 720 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 721 722 // Duplicate multiple commits without a direct ancestry relationship after a 723 // single commit which is an ancestor of one of the duplicated commits. 724 let output = work_dir.run_jj(["duplicate", "a3", "b1", "--after", "a2"]); 725 insta::assert_snapshot!(output, @r" 726 ------- stderr ------- 727 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 728 Duplicated 17072aa2b823 as pyoswmwk 0d11d466 a3 729 Duplicated dcc98bc8bbea as yqnpwwmq c32d1ccc b1 730 Rebased 2 commits onto duplicated commits 731 [EOF] 732 "); 733 insta::assert_snapshot!(get_log_output(&work_dir), @r" 734 @ 0cdd923e993a d2 735 ○ 0f21c5e185c5 d1 736 │ ○ 09560d60cac4 c2 737 │ ○ b27346e9a9bd c1 738 ├─╯ 739 │ ○ 7b44470918f4 b2 740 │ ○ dcc98bc8bbea b1 741 ├─╯ 742 │ ○ 955959f7bb42 a4 743 │ ○ 7b2b1ab433f0 a3 744 │ ├─╮ 745 │ │ ○ c32d1ccc8d5b b1 746 │ ○ │ 0d11d4667aa9 a3 747 │ ├─╯ 748 │ ○ 47df67757a64 a2 749 │ ○ 9e85a474f005 a1 750 ├─╯ 751 ◆ 000000000000 752 [EOF] 753 "); 754 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 755 756 // Duplicate multiple commits without a direct ancestry relationship after a 757 // single commit which is a descendant of one of the duplicated commits. 758 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--after", "a3"]); 759 insta::assert_snapshot!(output, @r" 760 ------- stderr ------- 761 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 762 Duplicated 9e85a474f005 as tpmlxquz 213aff50 (empty) a1 763 Duplicated dcc98bc8bbea as uukzylyy 67b82bab b1 764 Rebased 1 commits onto duplicated commits 765 [EOF] 766 "); 767 insta::assert_snapshot!(get_log_output(&work_dir), @r" 768 @ 0cdd923e993a d2 769 ○ 0f21c5e185c5 d1 770 │ ○ 09560d60cac4 c2 771 │ ○ b27346e9a9bd c1 772 ├─╯ 773 │ ○ 7b44470918f4 b2 774 │ ○ dcc98bc8bbea b1 775 ├─╯ 776 │ ○ 9457bd90ac07 a4 777 │ ├─╮ 778 │ │ ○ 67b82babd5f6 b1 779 │ ○ │ 213aff50a82b a1 780 │ ├─╯ 781 │ ○ 17072aa2b823 a3 782 │ ○ 47df67757a64 a2 783 │ ○ 9e85a474f005 a1 784 ├─╯ 785 ◆ 000000000000 786 [EOF] 787 "); 788 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 789 790 // Duplicate multiple commits without a direct ancestry relationship after 791 // multiple commits without a direct relationship to the duplicated commits. 792 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--after", "c1", "--after", "d1"]); 793 insta::assert_snapshot!(output, @r" 794 ------- stderr ------- 795 Duplicated 9e85a474f005 as knltnxnu ad0a80e9 a1 796 Duplicated dcc98bc8bbea as krtqozmx 840bbbe5 b1 797 Rebased 2 commits onto duplicated commits 798 Working copy (@) now at: nmzmmopx 9eeade97 d2 | d2 799 Parent commit (@-) : knltnxnu ad0a80e9 a1 800 Parent commit (@-) : krtqozmx 840bbbe5 b1 801 Added 3 files, modified 0 files, removed 0 files 802 [EOF] 803 "); 804 insta::assert_snapshot!(get_log_output(&work_dir), @r" 805 @ 9eeade97a2f7 d2 806 ├─╮ 807 │ │ ○ cd045e3862be c2 808 ╭─┬─╯ 809 │ ○ 840bbbe57acb b1 810 │ ├─╮ 811 ○ │ │ ad0a80e9b011 a1 812 ╰─┬─╮ 813 │ ○ 0f21c5e185c5 d1 814 ○ │ b27346e9a9bd c1 815 ├─╯ 816 ○ │ 7b44470918f4 b2 817 ○ │ dcc98bc8bbea b1 818 ├─╯ 819 │ ○ 196bc1f0efc1 a4 820 │ ○ 17072aa2b823 a3 821 │ ○ 47df67757a64 a2 822 │ ○ 9e85a474f005 a1 823 ├─╯ 824 ◆ 000000000000 825 [EOF] 826 "); 827 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 828 829 // Duplicate multiple commits without a direct ancestry relationship after 830 // multiple commits including an ancestor of one of the duplicated commits. 831 let output = work_dir.run_jj(["duplicate", "a3", "b1", "--after", "a1", "--after", "c1"]); 832 insta::assert_snapshot!(output, @r" 833 ------- stderr ------- 834 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 835 Duplicated 17072aa2b823 as wxzmtyol ade2ae32 a3 836 Duplicated dcc98bc8bbea as musouqkq e1eed3f1 b1 837 Rebased 4 commits onto duplicated commits 838 [EOF] 839 "); 840 insta::assert_snapshot!(get_log_output(&work_dir), @r" 841 @ 0cdd923e993a d2 842 ○ 0f21c5e185c5 d1 843 │ ○ 12a208423aa9 c2 844 │ ├─╮ 845 │ │ │ ○ c804d94310fd a4 846 │ │ │ ○ e22e44ff5f22 a3 847 │ │ │ ○ 6ee77bdfc821 a2 848 │ ╭─┬─╯ 849 │ │ ○ e1eed3f1c77c b1 850 │ │ ├─╮ 851 │ ○ │ │ ade2ae32950a a3 852 │ ╰─┬─╮ 853 │ │ ○ b27346e9a9bd c1 854 ├─────╯ 855 │ ○ 9e85a474f005 a1 856 ├───╯ 857 │ ○ 7b44470918f4 b2 858 │ ○ dcc98bc8bbea b1 859 ├─╯ 860 ◆ 000000000000 861 [EOF] 862 "); 863 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 864 865 // Duplicate multiple commits without a direct ancestry relationship after 866 // multiple commits including a descendant of one of the duplicated commits. 867 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--after", "a3", "--after", "c2"]); 868 insta::assert_snapshot!(output, @r" 869 ------- stderr ------- 870 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 871 Duplicated 9e85a474f005 as quyylypw c4820edd (empty) a1 872 Duplicated dcc98bc8bbea as prukwozq 20cfd11e b1 873 Rebased 1 commits onto duplicated commits 874 [EOF] 875 "); 876 insta::assert_snapshot!(get_log_output(&work_dir), @r" 877 @ 0cdd923e993a d2 878 ○ 0f21c5e185c5 d1 879 │ ○ 2d04909f04b5 a4 880 │ ├─╮ 881 │ │ ○ 20cfd11ee3c3 b1 882 │ │ ├─╮ 883 │ ○ │ │ c4820eddcd3c a1 884 │ ╰─┬─╮ 885 │ │ ○ 09560d60cac4 c2 886 │ │ ○ b27346e9a9bd c1 887 ├─────╯ 888 │ ○ 17072aa2b823 a3 889 │ ○ 47df67757a64 a2 890 │ ○ 9e85a474f005 a1 891 ├───╯ 892 │ ○ 7b44470918f4 b2 893 │ ○ dcc98bc8bbea b1 894 ├─╯ 895 ◆ 000000000000 896 [EOF] 897 "); 898 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 899 900 // Duplicate multiple commits with an ancestry relationship after a single 901 // commit without a direct relationship. 902 let output = work_dir.run_jj(["duplicate", "a1", "a3", "--after", "c2"]); 903 insta::assert_snapshot!(output, @r" 904 ------- stderr ------- 905 Duplicated 9e85a474f005 as vvvtksvt b44d23b4 a1 906 Duplicated 17072aa2b823 as yvrnrpnw ca8f08f6 a3 907 [EOF] 908 "); 909 insta::assert_snapshot!(get_log_output(&work_dir), @r" 910 @ 0cdd923e993a d2 911 ○ 0f21c5e185c5 d1 912 │ ○ ca8f08f66c5c a3 913 │ ○ b44d23b4c98e a1 914 │ ○ 09560d60cac4 c2 915 │ ○ b27346e9a9bd c1 916 ├─╯ 917 │ ○ 7b44470918f4 b2 918 │ ○ dcc98bc8bbea b1 919 ├─╯ 920 │ ○ 196bc1f0efc1 a4 921 │ ○ 17072aa2b823 a3 922 │ ○ 47df67757a64 a2 923 │ ○ 9e85a474f005 a1 924 ├─╯ 925 ◆ 000000000000 926 [EOF] 927 "); 928 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 929 930 // Duplicate multiple commits with an ancestry relationship after a single 931 // ancestor commit. 932 let output = work_dir.run_jj(["duplicate", "a2", "a3", "--after", "a1"]); 933 insta::assert_snapshot!(output, @r" 934 ------- stderr ------- 935 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 936 Warning: Duplicating commit 47df67757a64 as an ancestor of itself 937 Duplicated 47df67757a64 as sukptuzs 4324d289 a2 938 Duplicated 17072aa2b823 as rxnrppxl 47586b09 a3 939 Rebased 3 commits onto duplicated commits 940 [EOF] 941 "); 942 insta::assert_snapshot!(get_log_output(&work_dir), @r" 943 @ 0cdd923e993a d2 944 ○ 0f21c5e185c5 d1 945 │ ○ 09560d60cac4 c2 946 │ ○ b27346e9a9bd c1 947 ├─╯ 948 │ ○ 7b44470918f4 b2 949 │ ○ dcc98bc8bbea b1 950 ├─╯ 951 │ ○ 2174f54d55a9 a4 952 │ ○ 0224bfb4fc3d a3 953 │ ○ 22d3bdc60967 a2 954 │ ○ 47586b09a555 a3 955 │ ○ 4324d289e62c a2 956 │ ○ 9e85a474f005 a1 957 ├─╯ 958 ◆ 000000000000 959 [EOF] 960 "); 961 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 962 963 // Duplicate multiple commits with an ancestry relationship after a single 964 // descendant commit. 965 let output = work_dir.run_jj(["duplicate", "a1", "a2", "--after", "a3"]); 966 insta::assert_snapshot!(output, @r" 967 ------- stderr ------- 968 Warning: Duplicating commit 47df67757a64 as a descendant of itself 969 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 970 Duplicated 9e85a474f005 as rwkyzntp b68b9a00 (empty) a1 971 Duplicated 47df67757a64 as nqtyztop 0dd00ded (empty) a2 972 Rebased 1 commits onto duplicated commits 973 [EOF] 974 "); 975 insta::assert_snapshot!(get_log_output(&work_dir), @r" 976 @ 0cdd923e993a d2 977 ○ 0f21c5e185c5 d1 978 │ ○ 09560d60cac4 c2 979 │ ○ b27346e9a9bd c1 980 ├─╯ 981 │ ○ 7b44470918f4 b2 982 │ ○ dcc98bc8bbea b1 983 ├─╯ 984 │ ○ 4f02390e56aa a4 985 │ ○ 0dd00dedd0c5 a2 986 │ ○ b68b9a0073cb a1 987 │ ○ 17072aa2b823 a3 988 │ ○ 47df67757a64 a2 989 │ ○ 9e85a474f005 a1 990 ├─╯ 991 ◆ 000000000000 992 [EOF] 993 "); 994 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 995 996 // Duplicate multiple commits with an ancestry relationship after multiple 997 // commits without a direct relationship to the duplicated commits. 998 let output = work_dir.run_jj(["duplicate", "a1", "a3", "--after", "c2", "--after", "d2"]); 999 insta::assert_snapshot!(output, @r" 1000 ------- stderr ------- 1001 Duplicated 9e85a474f005 as nwmqwkzz eb455287 a1 1002 Duplicated 17072aa2b823 as uwrrnrtx 94a1bd80 a3 1003 [EOF] 1004 "); 1005 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1006 ○ 94a1bd8080c6 a3 1007 ○ eb455287f1eb a1 1008 ├─╮ 1009 │ @ 0cdd923e993a d2 1010 │ ○ 0f21c5e185c5 d1 1011 ○ │ 09560d60cac4 c2 1012 ○ │ b27346e9a9bd c1 1013 ├─╯ 1014 │ ○ 7b44470918f4 b2 1015 │ ○ dcc98bc8bbea b1 1016 ├─╯ 1017 │ ○ 196bc1f0efc1 a4 1018 │ ○ 17072aa2b823 a3 1019 │ ○ 47df67757a64 a2 1020 │ ○ 9e85a474f005 a1 1021 ├─╯ 1022 ◆ 000000000000 1023 [EOF] 1024 "); 1025 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1026 1027 // Duplicate multiple commits with an ancestry relationship after multiple 1028 // commits including an ancestor of one of the duplicated commits. 1029 let output = work_dir.run_jj(["duplicate", "a3", "a4", "--after", "a2", "--after", "c2"]); 1030 insta::assert_snapshot!(output, @r" 1031 ------- stderr ------- 1032 Warning: Duplicating commit 196bc1f0efc1 as an ancestor of itself 1033 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1034 Duplicated 17072aa2b823 as wunttkrp 1ce432e1 a3 1035 Duplicated 196bc1f0efc1 as puxpuzrm 14728ee8 a4 1036 Rebased 2 commits onto duplicated commits 1037 [EOF] 1038 "); 1039 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1040 @ 0cdd923e993a d2 1041 ○ 0f21c5e185c5 d1 1042 │ ○ 5fa41821880b a4 1043 │ ○ 52554e3e9729 a3 1044 │ ○ 14728ee84976 a4 1045 │ ○ 1ce432e1b0ea a3 1046 │ ├─╮ 1047 │ │ ○ 09560d60cac4 c2 1048 │ │ ○ b27346e9a9bd c1 1049 ├───╯ 1050 │ ○ 47df67757a64 a2 1051 │ ○ 9e85a474f005 a1 1052 ├─╯ 1053 │ ○ 7b44470918f4 b2 1054 │ ○ dcc98bc8bbea b1 1055 ├─╯ 1056 ◆ 000000000000 1057 [EOF] 1058 "); 1059 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1060 1061 // Duplicate multiple commits with an ancestry relationship after multiple 1062 // commits including a descendant of one of the duplicated commits. 1063 let output = work_dir.run_jj(["duplicate", "a1", "a2", "--after", "a3", "--after", "c2"]); 1064 insta::assert_snapshot!(output, @r" 1065 ------- stderr ------- 1066 Warning: Duplicating commit 47df67757a64 as a descendant of itself 1067 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1068 Duplicated 9e85a474f005 as zwvplpop 67dd65d3 (empty) a1 1069 Duplicated 47df67757a64 as znsksvls 7536fd44 (empty) a2 1070 Rebased 1 commits onto duplicated commits 1071 [EOF] 1072 "); 1073 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1074 @ 0cdd923e993a d2 1075 ○ 0f21c5e185c5 d1 1076 │ ○ 83aa2cfb2448 a4 1077 │ ○ 7536fd4475cd a2 1078 │ ○ 67dd65d3d47a a1 1079 │ ├─╮ 1080 │ │ ○ 09560d60cac4 c2 1081 │ │ ○ b27346e9a9bd c1 1082 ├───╯ 1083 │ ○ 17072aa2b823 a3 1084 │ ○ 47df67757a64 a2 1085 │ ○ 9e85a474f005 a1 1086 ├─╯ 1087 │ ○ 7b44470918f4 b2 1088 │ ○ dcc98bc8bbea b1 1089 ├─╯ 1090 ◆ 000000000000 1091 [EOF] 1092 "); 1093 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1094 1095 // Should error if a loop will be created. 1096 let output = work_dir.run_jj(["duplicate", "a1", "--after", "b1", "--after", "b2"]); 1097 insta::assert_snapshot!(output, @r" 1098 ------- stderr ------- 1099 Error: Refusing to create a loop: commit 7b44470918f4 would be both an ancestor and a descendant of the duplicated commits 1100 [EOF] 1101 [exit status: 1] 1102 "); 1103} 1104 1105#[test] 1106fn test_duplicate_insert_before() { 1107 let test_env = TestEnvironment::default(); 1108 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 1109 let work_dir = test_env.work_dir("repo"); 1110 1111 create_commit(&work_dir, "a1", &[]); 1112 create_commit(&work_dir, "a2", &["a1"]); 1113 create_commit(&work_dir, "a3", &["a2"]); 1114 create_commit(&work_dir, "a4", &["a3"]); 1115 create_commit(&work_dir, "b1", &[]); 1116 create_commit(&work_dir, "b2", &["b1"]); 1117 create_commit(&work_dir, "c1", &[]); 1118 create_commit(&work_dir, "c2", &["c1"]); 1119 create_commit(&work_dir, "d1", &[]); 1120 create_commit(&work_dir, "d2", &["d1"]); 1121 let setup_opid = work_dir.current_operation_id(); 1122 1123 // Test the setup 1124 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1125 @ 0cdd923e993a d2 1126 ○ 0f21c5e185c5 d1 1127 │ ○ 09560d60cac4 c2 1128 │ ○ b27346e9a9bd c1 1129 ├─╯ 1130 │ ○ 7b44470918f4 b2 1131 │ ○ dcc98bc8bbea b1 1132 ├─╯ 1133 │ ○ 196bc1f0efc1 a4 1134 │ ○ 17072aa2b823 a3 1135 │ ○ 47df67757a64 a2 1136 │ ○ 9e85a474f005 a1 1137 ├─╯ 1138 ◆ 000000000000 1139 [EOF] 1140 "); 1141 1142 // Duplicate a single commit before a single commit with no direct relationship. 1143 let output = work_dir.run_jj(["duplicate", "a1", "--before", "b2"]); 1144 insta::assert_snapshot!(output, @r" 1145 ------- stderr ------- 1146 Duplicated 9e85a474f005 as pzsxstzt b71e23da a1 1147 Rebased 1 commits onto duplicated commits 1148 [EOF] 1149 "); 1150 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1151 @ 0cdd923e993a d2 1152 ○ 0f21c5e185c5 d1 1153 │ ○ 09560d60cac4 c2 1154 │ ○ b27346e9a9bd c1 1155 ├─╯ 1156 │ ○ af12531fa2dc b2 1157 │ ○ b71e23da3559 a1 1158 │ ○ dcc98bc8bbea b1 1159 ├─╯ 1160 │ ○ 196bc1f0efc1 a4 1161 │ ○ 17072aa2b823 a3 1162 │ ○ 47df67757a64 a2 1163 │ ○ 9e85a474f005 a1 1164 ├─╯ 1165 ◆ 000000000000 1166 [EOF] 1167 "); 1168 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1169 1170 // Duplicate a single commit before a single ancestor commit. 1171 let output = work_dir.run_jj(["duplicate", "a3", "--before", "a1"]); 1172 insta::assert_snapshot!(output, @r" 1173 ------- stderr ------- 1174 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1175 Duplicated 17072aa2b823 as qmkrwlvp 2108707c a3 1176 Rebased 4 commits onto duplicated commits 1177 [EOF] 1178 "); 1179 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1180 @ 0cdd923e993a d2 1181 ○ 0f21c5e185c5 d1 1182 │ ○ ef93a98b9dba a4 1183 │ ○ 5952e93b6237 a3 1184 │ ○ f9baa38681ce a2 1185 │ ○ 3096149ab785 a1 1186 │ ○ 2108707c8d39 a3 1187 ├─╯ 1188 │ ○ 09560d60cac4 c2 1189 │ ○ b27346e9a9bd c1 1190 ├─╯ 1191 │ ○ 7b44470918f4 b2 1192 │ ○ dcc98bc8bbea b1 1193 ├─╯ 1194 ◆ 000000000000 1195 [EOF] 1196 "); 1197 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1198 1199 // Duplicate a single commit before a single descendant commit. 1200 let output = work_dir.run_jj(["duplicate", "a1", "--before", "a3"]); 1201 insta::assert_snapshot!(output, @r" 1202 ------- stderr ------- 1203 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1204 Duplicated 9e85a474f005 as qwyusntz 2fe2d212 (empty) a1 1205 Rebased 2 commits onto duplicated commits 1206 [EOF] 1207 "); 1208 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1209 @ 0cdd923e993a d2 1210 ○ 0f21c5e185c5 d1 1211 │ ○ 09560d60cac4 c2 1212 │ ○ b27346e9a9bd c1 1213 ├─╯ 1214 │ ○ 7b44470918f4 b2 1215 │ ○ dcc98bc8bbea b1 1216 ├─╯ 1217 │ ○ 664fce416f57 a4 1218 │ ○ 547efe815e18 a3 1219 │ ○ 2fe2d21257c9 a1 1220 │ ○ 47df67757a64 a2 1221 │ ○ 9e85a474f005 a1 1222 ├─╯ 1223 ◆ 000000000000 1224 [EOF] 1225 "); 1226 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1227 1228 // Duplicate a single commit before multiple commits with no direct 1229 // relationship. 1230 let output = work_dir.run_jj(["duplicate", "a1", "--before", "b2", "--before", "c2"]); 1231 insta::assert_snapshot!(output, @r" 1232 ------- stderr ------- 1233 Duplicated 9e85a474f005 as soqnvnyz 3449bde2 a1 1234 Rebased 2 commits onto duplicated commits 1235 [EOF] 1236 "); 1237 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1238 @ 0cdd923e993a d2 1239 ○ 0f21c5e185c5 d1 1240 │ ○ c997a412ac93 c2 1241 │ │ ○ e570747744ed b2 1242 │ ├─╯ 1243 │ ○ 3449bde20037 a1 1244 │ ├─╮ 1245 │ │ ○ b27346e9a9bd c1 1246 ├───╯ 1247 │ ○ dcc98bc8bbea b1 1248 ├─╯ 1249 │ ○ 196bc1f0efc1 a4 1250 │ ○ 17072aa2b823 a3 1251 │ ○ 47df67757a64 a2 1252 │ ○ 9e85a474f005 a1 1253 ├─╯ 1254 ◆ 000000000000 1255 [EOF] 1256 "); 1257 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1258 1259 // Duplicate a single commit before multiple commits including an ancestor. 1260 let output = work_dir.run_jj(["duplicate", "a3", "--before", "a2", "--before", "b2"]); 1261 insta::assert_snapshot!(output, @r" 1262 ------- stderr ------- 1263 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1264 Duplicated 17072aa2b823 as nsrwusvy 8648c1c8 a3 1265 Rebased 4 commits onto duplicated commits 1266 [EOF] 1267 "); 1268 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1269 @ 0cdd923e993a d2 1270 ○ 0f21c5e185c5 d1 1271 │ ○ 09560d60cac4 c2 1272 │ ○ b27346e9a9bd c1 1273 ├─╯ 1274 │ ○ 1722fb59dee6 b2 1275 │ │ ○ cdeff7751fb6 a4 1276 │ │ ○ 28f70dc150b8 a3 1277 │ │ ○ f38e6d30913d a2 1278 │ ├─╯ 1279 │ ○ 8648c1c894f0 a3 1280 │ ├─╮ 1281 │ │ ○ dcc98bc8bbea b1 1282 ├───╯ 1283 │ ○ 9e85a474f005 a1 1284 ├─╯ 1285 ◆ 000000000000 1286 [EOF] 1287 "); 1288 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1289 1290 // Duplicate a single commit before multiple commits including a descendant. 1291 let output = work_dir.run_jj(["duplicate", "a1", "--before", "a3", "--before", "b2"]); 1292 insta::assert_snapshot!(output, @r" 1293 ------- stderr ------- 1294 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1295 Duplicated 9e85a474f005 as xpnwykqz 72cf8983 (empty) a1 1296 Rebased 3 commits onto duplicated commits 1297 [EOF] 1298 "); 1299 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1300 @ 0cdd923e993a d2 1301 ○ 0f21c5e185c5 d1 1302 │ ○ 09560d60cac4 c2 1303 │ ○ b27346e9a9bd c1 1304 ├─╯ 1305 │ ○ d78b124079a4 b2 1306 │ │ ○ 490d6138ef36 a4 1307 │ │ ○ e349d271ef64 a3 1308 │ ├─╯ 1309 │ ○ 72cf89838d1a a1 1310 │ ├─╮ 1311 │ │ ○ dcc98bc8bbea b1 1312 ├───╯ 1313 │ ○ 47df67757a64 a2 1314 │ ○ 9e85a474f005 a1 1315 ├─╯ 1316 ◆ 000000000000 1317 [EOF] 1318 "); 1319 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1320 1321 // Duplicate multiple commits without a direct ancestry relationship before a 1322 // single commit without a direct relationship. 1323 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--before", "c1"]); 1324 insta::assert_snapshot!(output, @r" 1325 ------- stderr ------- 1326 Duplicated 9e85a474f005 as sryyqqkq fa625d74 a1 1327 Duplicated dcc98bc8bbea as pxnqtknr 2233b9a8 b1 1328 Rebased 2 commits onto duplicated commits 1329 [EOF] 1330 "); 1331 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1332 @ 0cdd923e993a d2 1333 ○ 0f21c5e185c5 d1 1334 │ ○ cf7c4c4cc8bc c2 1335 │ ○ 6412acdac711 c1 1336 │ ├─╮ 1337 │ │ ○ 2233b9a87d86 b1 1338 ├───╯ 1339 │ ○ fa625d74e0ae a1 1340 ├─╯ 1341 │ ○ 7b44470918f4 b2 1342 │ ○ dcc98bc8bbea b1 1343 ├─╯ 1344 │ ○ 196bc1f0efc1 a4 1345 │ ○ 17072aa2b823 a3 1346 │ ○ 47df67757a64 a2 1347 │ ○ 9e85a474f005 a1 1348 ├─╯ 1349 ◆ 000000000000 1350 [EOF] 1351 "); 1352 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1353 1354 // Duplicate multiple commits without a direct ancestry relationship before a 1355 // single commit which is an ancestor of one of the duplicated commits. 1356 let output = work_dir.run_jj(["duplicate", "a3", "b1", "--before", "a2"]); 1357 insta::assert_snapshot!(output, @r" 1358 ------- stderr ------- 1359 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1360 Duplicated 17072aa2b823 as pyoswmwk cad067c7 a3 1361 Duplicated dcc98bc8bbea as yqnpwwmq 6675be66 b1 1362 Rebased 3 commits onto duplicated commits 1363 [EOF] 1364 "); 1365 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1366 @ 0cdd923e993a d2 1367 ○ 0f21c5e185c5 d1 1368 │ ○ 09560d60cac4 c2 1369 │ ○ b27346e9a9bd c1 1370 ├─╯ 1371 │ ○ 7b44470918f4 b2 1372 │ ○ dcc98bc8bbea b1 1373 ├─╯ 1374 │ ○ 17391b843937 a4 1375 │ ○ 23f979220309 a3 1376 │ ○ 15a3207cfa72 a2 1377 │ ├─╮ 1378 │ │ ○ 6675be66b280 b1 1379 │ ○ │ cad067c7d304 a3 1380 │ ├─╯ 1381 │ ○ 9e85a474f005 a1 1382 ├─╯ 1383 ◆ 000000000000 1384 [EOF] 1385 "); 1386 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1387 1388 // Duplicate multiple commits without a direct ancestry relationship before a 1389 // single commit which is a descendant of one of the duplicated commits. 1390 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--before", "a3"]); 1391 insta::assert_snapshot!(output, @r" 1392 ------- stderr ------- 1393 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1394 Duplicated 9e85a474f005 as tpmlxquz 4d4dc78c (empty) a1 1395 Duplicated dcc98bc8bbea as uukzylyy a065abc9 b1 1396 Rebased 2 commits onto duplicated commits 1397 [EOF] 1398 "); 1399 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1400 @ 0cdd923e993a d2 1401 ○ 0f21c5e185c5 d1 1402 │ ○ 09560d60cac4 c2 1403 │ ○ b27346e9a9bd c1 1404 ├─╯ 1405 │ ○ 7b44470918f4 b2 1406 │ ○ dcc98bc8bbea b1 1407 ├─╯ 1408 │ ○ adb92c147726 a4 1409 │ ○ fb156cb07e68 a3 1410 │ ├─╮ 1411 │ │ ○ a065abc9c61f b1 1412 │ ○ │ 4d4dc78c70a7 a1 1413 │ ├─╯ 1414 │ ○ 47df67757a64 a2 1415 │ ○ 9e85a474f005 a1 1416 ├─╯ 1417 ◆ 000000000000 1418 [EOF] 1419 "); 1420 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1421 1422 // Duplicate multiple commits without a direct ancestry relationship before 1423 // multiple commits without a direct relationship to the duplicated commits. 1424 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--before", "c1", "--before", "d1"]); 1425 insta::assert_snapshot!(output, @r" 1426 ------- stderr ------- 1427 Duplicated 9e85a474f005 as knltnxnu 056a0cb3 a1 1428 Duplicated dcc98bc8bbea as krtqozmx fb68a539 b1 1429 Rebased 4 commits onto duplicated commits 1430 Working copy (@) now at: nmzmmopx 89f9b379 d2 | d2 1431 Parent commit (@-) : xznxytkn 771d0e16 d1 | d1 1432 Added 2 files, modified 0 files, removed 0 files 1433 [EOF] 1434 "); 1435 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1436 @ 89f9b37923a9 d2 1437 ○ 771d0e16b40c d1 1438 ├─╮ 1439 │ │ ○ 7e7653d32cf1 c2 1440 │ │ ○ a83b8a44f3fc c1 1441 ╭─┬─╯ 1442 │ ○ fb68a539aea7 b1 1443 ○ │ 056a0cb391f8 a1 1444 ├─╯ 1445 │ ○ 7b44470918f4 b2 1446 │ ○ dcc98bc8bbea b1 1447 ├─╯ 1448 │ ○ 196bc1f0efc1 a4 1449 │ ○ 17072aa2b823 a3 1450 │ ○ 47df67757a64 a2 1451 │ ○ 9e85a474f005 a1 1452 ├─╯ 1453 ◆ 000000000000 1454 [EOF] 1455 "); 1456 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1457 1458 // Duplicate multiple commits without a direct ancestry relationship before 1459 // multiple commits including an ancestor of one of the duplicated commits. 1460 let output = work_dir.run_jj(["duplicate", "a3", "b1", "--before", "a1", "--before", "c1"]); 1461 insta::assert_snapshot!(output, @r" 1462 ------- stderr ------- 1463 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1464 Duplicated 17072aa2b823 as wxzmtyol 31ca96b8 a3 1465 Duplicated dcc98bc8bbea as musouqkq 4748cf83 b1 1466 Rebased 6 commits onto duplicated commits 1467 [EOF] 1468 "); 1469 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1470 @ 0cdd923e993a d2 1471 ○ 0f21c5e185c5 d1 1472 │ ○ aa431fa5a467 c2 1473 │ ○ f99bc6bf1b1c c1 1474 │ ├─╮ 1475 │ │ │ ○ a38ca6dc28f3 a4 1476 │ │ │ ○ 16e3d6c1562a a3 1477 │ │ │ ○ 84b5c2b584d1 a2 1478 │ │ │ ○ cc4ae3a9a31d a1 1479 │ ╭─┬─╯ 1480 │ │ ○ 4748cf83e26e b1 1481 ├───╯ 1482 │ ○ 31ca96b88527 a3 1483 ├─╯ 1484 │ ○ 7b44470918f4 b2 1485 │ ○ dcc98bc8bbea b1 1486 ├─╯ 1487 ◆ 000000000000 1488 [EOF] 1489 "); 1490 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1491 1492 // Duplicate multiple commits without a direct ancestry relationship before 1493 // multiple commits including a descendant of one of the duplicated commits. 1494 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--before", "a3", "--before", "c2"]); 1495 insta::assert_snapshot!(output, @r" 1496 ------- stderr ------- 1497 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1498 Duplicated 9e85a474f005 as quyylypw 3eefd57d (empty) a1 1499 Duplicated dcc98bc8bbea as prukwozq ed86e70f b1 1500 Rebased 3 commits onto duplicated commits 1501 [EOF] 1502 "); 1503 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1504 @ 0cdd923e993a d2 1505 ○ 0f21c5e185c5 d1 1506 │ ○ 1c0d40fa21ea c2 1507 │ ├─╮ 1508 │ │ │ ○ c31979bb15d4 a4 1509 │ │ │ ○ 8daf2e842412 a3 1510 │ ╭─┬─╯ 1511 │ │ ○ ed86e70f497f b1 1512 │ │ ├─╮ 1513 │ ○ │ │ 3eefd57d676b a1 1514 │ ╰─┬─╮ 1515 │ │ ○ b27346e9a9bd c1 1516 ├─────╯ 1517 │ ○ 47df67757a64 a2 1518 │ ○ 9e85a474f005 a1 1519 ├───╯ 1520 │ ○ 7b44470918f4 b2 1521 │ ○ dcc98bc8bbea b1 1522 ├─╯ 1523 ◆ 000000000000 1524 [EOF] 1525 "); 1526 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1527 1528 // Duplicate multiple commits with an ancestry relationship before a single 1529 // commit without a direct relationship. 1530 let output = work_dir.run_jj(["duplicate", "a1", "a3", "--before", "c2"]); 1531 insta::assert_snapshot!(output, @r" 1532 ------- stderr ------- 1533 Duplicated 9e85a474f005 as vvvtksvt baee09af a1 1534 Duplicated 17072aa2b823 as yvrnrpnw c17818c1 a3 1535 Rebased 1 commits onto duplicated commits 1536 [EOF] 1537 "); 1538 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1539 @ 0cdd923e993a d2 1540 ○ 0f21c5e185c5 d1 1541 │ ○ 4a25ce233a30 c2 1542 │ ○ c17818c175df a3 1543 │ ○ baee09af0f75 a1 1544 │ ○ b27346e9a9bd c1 1545 ├─╯ 1546 │ ○ 7b44470918f4 b2 1547 │ ○ dcc98bc8bbea b1 1548 ├─╯ 1549 │ ○ 196bc1f0efc1 a4 1550 │ ○ 17072aa2b823 a3 1551 │ ○ 47df67757a64 a2 1552 │ ○ 9e85a474f005 a1 1553 ├─╯ 1554 ◆ 000000000000 1555 [EOF] 1556 "); 1557 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1558 1559 // Duplicate multiple commits with an ancestry relationship before a single 1560 // ancestor commit. 1561 let output = work_dir.run_jj(["duplicate", "a1", "a3", "--before", "a1"]); 1562 insta::assert_snapshot!(output, @r" 1563 ------- stderr ------- 1564 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1565 Warning: Duplicating commit 9e85a474f005 as an ancestor of itself 1566 Duplicated 9e85a474f005 as sukptuzs ad0234a3 a1 1567 Duplicated 17072aa2b823 as rxnrppxl e64dcdd1 a3 1568 Rebased 4 commits onto duplicated commits 1569 [EOF] 1570 "); 1571 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1572 @ 0cdd923e993a d2 1573 ○ 0f21c5e185c5 d1 1574 │ ○ 76cbe9641be2 a4 1575 │ ○ 140c783a30c6 a3 1576 │ ○ 940c74f17140 a2 1577 │ ○ d359f7d9dfe7 a1 1578 │ ○ e64dcdd1d1d1 a3 1579 │ ○ ad0234a34661 a1 1580 ├─╯ 1581 │ ○ 09560d60cac4 c2 1582 │ ○ b27346e9a9bd c1 1583 ├─╯ 1584 │ ○ 7b44470918f4 b2 1585 │ ○ dcc98bc8bbea b1 1586 ├─╯ 1587 ◆ 000000000000 1588 [EOF] 1589 "); 1590 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1591 1592 // Duplicate multiple commits with an ancestry relationship before a single 1593 // descendant commit. 1594 let output = work_dir.run_jj(["duplicate", "a1", "a2", "--before", "a3"]); 1595 insta::assert_snapshot!(output, @r" 1596 ------- stderr ------- 1597 Warning: Duplicating commit 47df67757a64 as a descendant of itself 1598 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1599 Duplicated 9e85a474f005 as rwkyzntp e614bda1 (empty) a1 1600 Duplicated 47df67757a64 as nqtyztop 5de52186 (empty) a2 1601 Rebased 2 commits onto duplicated commits 1602 [EOF] 1603 "); 1604 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1605 @ 0cdd923e993a d2 1606 ○ 0f21c5e185c5 d1 1607 │ ○ 09560d60cac4 c2 1608 │ ○ b27346e9a9bd c1 1609 ├─╯ 1610 │ ○ 7b44470918f4 b2 1611 │ ○ dcc98bc8bbea b1 1612 ├─╯ 1613 │ ○ 585cb65f6d57 a4 1614 │ ○ b75dd23ffef0 a3 1615 │ ○ 5de52186bdf3 a2 1616 │ ○ e614bda1f2dc a1 1617 │ ○ 47df67757a64 a2 1618 │ ○ 9e85a474f005 a1 1619 ├─╯ 1620 ◆ 000000000000 1621 [EOF] 1622 "); 1623 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1624 1625 // Duplicate multiple commits with an ancestry relationship before multiple 1626 // commits without a direct relationship to the duplicated commits. 1627 let output = work_dir.run_jj(["duplicate", "a1", "a3", "--before", "c2", "--before", "d2"]); 1628 insta::assert_snapshot!(output, @r" 1629 ------- stderr ------- 1630 Duplicated 9e85a474f005 as nwmqwkzz 9963be9b a1 1631 Duplicated 17072aa2b823 as uwrrnrtx a5eee87f a3 1632 Rebased 2 commits onto duplicated commits 1633 Working copy (@) now at: nmzmmopx 8161bbbc d2 | d2 1634 Parent commit (@-) : uwrrnrtx a5eee87f a3 1635 Added 3 files, modified 0 files, removed 0 files 1636 [EOF] 1637 "); 1638 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1639 @ 8161bbbc1341 d2 1640 │ ○ 62eea4c098aa c2 1641 ├─╯ 1642 ○ a5eee87f5120 a3 1643 ○ 9963be9be4cd a1 1644 ├─╮ 1645 │ ○ 0f21c5e185c5 d1 1646 ○ │ b27346e9a9bd c1 1647 ├─╯ 1648 │ ○ 7b44470918f4 b2 1649 │ ○ dcc98bc8bbea b1 1650 ├─╯ 1651 │ ○ 196bc1f0efc1 a4 1652 │ ○ 17072aa2b823 a3 1653 │ ○ 47df67757a64 a2 1654 │ ○ 9e85a474f005 a1 1655 ├─╯ 1656 ◆ 000000000000 1657 [EOF] 1658 "); 1659 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1660 1661 // Duplicate multiple commits with an ancestry relationship before multiple 1662 // commits including an ancestor of one of the duplicated commits. 1663 let output = work_dir.run_jj(["duplicate", "a3", "a4", "--before", "a2", "--before", "c2"]); 1664 insta::assert_snapshot!(output, @r" 1665 ------- stderr ------- 1666 Warning: Duplicating commit 196bc1f0efc1 as an ancestor of itself 1667 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1668 Duplicated 17072aa2b823 as wunttkrp 11fcc721 a3 1669 Duplicated 196bc1f0efc1 as puxpuzrm 3a0d76b0 a4 1670 Rebased 4 commits onto duplicated commits 1671 [EOF] 1672 "); 1673 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1674 @ 0cdd923e993a d2 1675 ○ 0f21c5e185c5 d1 1676 │ ○ c7a0da69006c c2 1677 │ │ ○ 8f35827d9ec9 a4 1678 │ │ ○ 1ac63ccfda31 a3 1679 │ │ ○ 96b02cd292f9 a2 1680 │ ├─╯ 1681 │ ○ 3a0d76b0e8c2 a4 1682 │ ○ 11fcc72145cc a3 1683 │ ├─╮ 1684 │ │ ○ b27346e9a9bd c1 1685 ├───╯ 1686 │ ○ 9e85a474f005 a1 1687 ├─╯ 1688 │ ○ 7b44470918f4 b2 1689 │ ○ dcc98bc8bbea b1 1690 ├─╯ 1691 ◆ 000000000000 1692 [EOF] 1693 "); 1694 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1695 1696 // Duplicate multiple commits with an ancestry relationship before multiple 1697 // commits including a descendant of one of the duplicated commits. 1698 let output = work_dir.run_jj(["duplicate", "a1", "a2", "--before", "a3", "--before", "c2"]); 1699 insta::assert_snapshot!(output, @r" 1700 ------- stderr ------- 1701 Warning: Duplicating commit 47df67757a64 as a descendant of itself 1702 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1703 Duplicated 9e85a474f005 as zwvplpop 311e39e4 (empty) a1 1704 Duplicated 47df67757a64 as znsksvls fdaa673d (empty) a2 1705 Rebased 3 commits onto duplicated commits 1706 [EOF] 1707 "); 1708 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1709 @ 0cdd923e993a d2 1710 ○ 0f21c5e185c5 d1 1711 │ ○ f1f4e0efe9fb c2 1712 │ │ ○ a5af2ec2ff05 a4 1713 │ │ ○ 5d98ceaab6a5 a3 1714 │ ├─╯ 1715 │ ○ fdaa673dff14 a2 1716 │ ○ 311e39e4de28 a1 1717 │ ├─╮ 1718 │ │ ○ b27346e9a9bd c1 1719 ├───╯ 1720 │ ○ 47df67757a64 a2 1721 │ ○ 9e85a474f005 a1 1722 ├─╯ 1723 │ ○ 7b44470918f4 b2 1724 │ ○ dcc98bc8bbea b1 1725 ├─╯ 1726 ◆ 000000000000 1727 [EOF] 1728 "); 1729 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1730 1731 // Should error if a loop will be created. 1732 let output = work_dir.run_jj(["duplicate", "a1", "--before", "b1", "--before", "b2"]); 1733 insta::assert_snapshot!(output, @r" 1734 ------- stderr ------- 1735 Error: Refusing to create a loop: commit dcc98bc8bbea would be both an ancestor and a descendant of the duplicated commits 1736 [EOF] 1737 [exit status: 1] 1738 "); 1739} 1740 1741#[test] 1742fn test_duplicate_insert_after_before() { 1743 let test_env = TestEnvironment::default(); 1744 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 1745 let work_dir = test_env.work_dir("repo"); 1746 1747 create_commit(&work_dir, "a1", &[]); 1748 create_commit(&work_dir, "a2", &["a1"]); 1749 create_commit(&work_dir, "a3", &["a2"]); 1750 create_commit(&work_dir, "a4", &["a3"]); 1751 create_commit(&work_dir, "b1", &[]); 1752 create_commit(&work_dir, "b2", &["b1"]); 1753 create_commit(&work_dir, "c1", &[]); 1754 create_commit(&work_dir, "c2", &["c1"]); 1755 create_commit(&work_dir, "d1", &[]); 1756 create_commit(&work_dir, "d2", &["d1"]); 1757 let setup_opid = work_dir.current_operation_id(); 1758 1759 // Test the setup 1760 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1761 @ 0cdd923e993a d2 1762 ○ 0f21c5e185c5 d1 1763 │ ○ 09560d60cac4 c2 1764 │ ○ b27346e9a9bd c1 1765 ├─╯ 1766 │ ○ 7b44470918f4 b2 1767 │ ○ dcc98bc8bbea b1 1768 ├─╯ 1769 │ ○ 196bc1f0efc1 a4 1770 │ ○ 17072aa2b823 a3 1771 │ ○ 47df67757a64 a2 1772 │ ○ 9e85a474f005 a1 1773 ├─╯ 1774 ◆ 000000000000 1775 [EOF] 1776 "); 1777 1778 // Duplicate a single commit in between commits with no direct relationship. 1779 let output = work_dir.run_jj(["duplicate", "a1", "--before", "b2", "--after", "c2"]); 1780 insta::assert_snapshot!(output, @r" 1781 ------- stderr ------- 1782 Duplicated 9e85a474f005 as pzsxstzt afc97ea4 a1 1783 Rebased 1 commits onto duplicated commits 1784 [EOF] 1785 "); 1786 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1787 @ 0cdd923e993a d2 1788 ○ 0f21c5e185c5 d1 1789 │ ○ 41f0321a79b8 b2 1790 │ ├─╮ 1791 │ │ ○ afc97ea480c1 a1 1792 │ │ ○ 09560d60cac4 c2 1793 │ │ ○ b27346e9a9bd c1 1794 ├───╯ 1795 │ ○ dcc98bc8bbea b1 1796 ├─╯ 1797 │ ○ 196bc1f0efc1 a4 1798 │ ○ 17072aa2b823 a3 1799 │ ○ 47df67757a64 a2 1800 │ ○ 9e85a474f005 a1 1801 ├─╯ 1802 ◆ 000000000000 1803 [EOF] 1804 "); 1805 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1806 1807 // Duplicate a single commit in between ancestor commits. 1808 let output = work_dir.run_jj(["duplicate", "a3", "--before", "a2", "--after", "a1"]); 1809 insta::assert_snapshot!(output, @r" 1810 ------- stderr ------- 1811 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1812 Duplicated 17072aa2b823 as qmkrwlvp fd3c891b a3 1813 Rebased 3 commits onto duplicated commits 1814 [EOF] 1815 "); 1816 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1817 @ 0cdd923e993a d2 1818 ○ 0f21c5e185c5 d1 1819 │ ○ 09560d60cac4 c2 1820 │ ○ b27346e9a9bd c1 1821 ├─╯ 1822 │ ○ 7b44470918f4 b2 1823 │ ○ dcc98bc8bbea b1 1824 ├─╯ 1825 │ ○ 027d38df36fa a4 1826 │ ○ 6cb0f5884a35 a3 1827 │ ○ 80e3e40b66f0 a2 1828 │ ○ fd3c891b8b97 a3 1829 │ ○ 9e85a474f005 a1 1830 ├─╯ 1831 ◆ 000000000000 1832 [EOF] 1833 "); 1834 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1835 1836 // Duplicate a single commit in between an ancestor commit and a commit with no 1837 // direct relationship. 1838 let output = work_dir.run_jj(["duplicate", "a3", "--before", "a2", "--after", "b2"]); 1839 insta::assert_snapshot!(output, @r" 1840 ------- stderr ------- 1841 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 1842 Duplicated 17072aa2b823 as qwyusntz 4d69f69c a3 1843 Rebased 3 commits onto duplicated commits 1844 [EOF] 1845 "); 1846 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1847 @ 0cdd923e993a d2 1848 ○ 0f21c5e185c5 d1 1849 │ ○ 09560d60cac4 c2 1850 │ ○ b27346e9a9bd c1 1851 ├─╯ 1852 │ ○ 1e4a9c0c8247 a4 1853 │ ○ 416da6f255ef a3 1854 │ ○ 335701a7e2f7 a2 1855 │ ├─╮ 1856 │ │ ○ 4d69f69ca987 a3 1857 │ │ ○ 7b44470918f4 b2 1858 │ │ ○ dcc98bc8bbea b1 1859 ├───╯ 1860 │ ○ 9e85a474f005 a1 1861 ├─╯ 1862 ◆ 000000000000 1863 [EOF] 1864 "); 1865 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1866 1867 // Duplicate a single commit in between descendant commits. 1868 let output = work_dir.run_jj(["duplicate", "a1", "--after", "a3", "--before", "a4"]); 1869 insta::assert_snapshot!(output, @r" 1870 ------- stderr ------- 1871 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1872 Duplicated 9e85a474f005 as soqnvnyz 00811f7c (empty) a1 1873 Rebased 1 commits onto duplicated commits 1874 [EOF] 1875 "); 1876 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1877 @ 0cdd923e993a d2 1878 ○ 0f21c5e185c5 d1 1879 │ ○ 09560d60cac4 c2 1880 │ ○ b27346e9a9bd c1 1881 ├─╯ 1882 │ ○ 7b44470918f4 b2 1883 │ ○ dcc98bc8bbea b1 1884 ├─╯ 1885 │ ○ d6d9a67a7882 a4 1886 │ ○ 00811f7ccdb5 a1 1887 │ ○ 17072aa2b823 a3 1888 │ ○ 47df67757a64 a2 1889 │ ○ 9e85a474f005 a1 1890 ├─╯ 1891 ◆ 000000000000 1892 [EOF] 1893 "); 1894 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1895 1896 // Duplicate a single commit in between a descendant commit and a commit with no 1897 // direct relationship. 1898 let output = work_dir.run_jj(["duplicate", "a1", "--after", "a3", "--before", "b2"]); 1899 insta::assert_snapshot!(output, @r" 1900 ------- stderr ------- 1901 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 1902 Duplicated 9e85a474f005 as nsrwusvy 0b89e8a3 (empty) a1 1903 Rebased 1 commits onto duplicated commits 1904 [EOF] 1905 "); 1906 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1907 @ 0cdd923e993a d2 1908 ○ 0f21c5e185c5 d1 1909 │ ○ 09560d60cac4 c2 1910 │ ○ b27346e9a9bd c1 1911 ├─╯ 1912 │ ○ 71f4a83f7122 b2 1913 │ ├─╮ 1914 │ │ ○ 0b89e8a32915 a1 1915 │ ○ │ dcc98bc8bbea b1 1916 ├─╯ │ 1917 │ ○ │ 196bc1f0efc1 a4 1918 │ ├─╯ 1919 │ ○ 17072aa2b823 a3 1920 │ ○ 47df67757a64 a2 1921 │ ○ 9e85a474f005 a1 1922 ├─╯ 1923 ◆ 000000000000 1924 [EOF] 1925 "); 1926 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1927 1928 // Duplicate a single commit in between an ancestor commit and a descendant 1929 // commit. 1930 let output = work_dir.run_jj(["duplicate", "a2", "--after", "a1", "--before", "a4"]); 1931 insta::assert_snapshot!(output, @r" 1932 ------- stderr ------- 1933 Duplicated 47df67757a64 as xpnwykqz 54cc0161 a2 1934 Rebased 1 commits onto duplicated commits 1935 [EOF] 1936 "); 1937 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1938 @ 0cdd923e993a d2 1939 ○ 0f21c5e185c5 d1 1940 │ ○ 09560d60cac4 c2 1941 │ ○ b27346e9a9bd c1 1942 ├─╯ 1943 │ ○ 7b44470918f4 b2 1944 │ ○ dcc98bc8bbea b1 1945 ├─╯ 1946 │ ○ b08d6199fab9 a4 1947 │ ├─╮ 1948 │ │ ○ 54cc0161a5db a2 1949 │ ○ │ 17072aa2b823 a3 1950 │ ○ │ 47df67757a64 a2 1951 │ ├─╯ 1952 │ ○ 9e85a474f005 a1 1953 ├─╯ 1954 ◆ 000000000000 1955 [EOF] 1956 "); 1957 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1958 1959 // Duplicate multiple commits without a direct ancestry relationship between 1960 // commits without a direct relationship. 1961 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--after", "c1", "--before", "d2"]); 1962 insta::assert_snapshot!(output, @r" 1963 ------- stderr ------- 1964 Duplicated 9e85a474f005 as sryyqqkq 44f57f24 a1 1965 Duplicated dcc98bc8bbea as pxnqtknr bcee4b60 b1 1966 Rebased 1 commits onto duplicated commits 1967 Working copy (@) now at: nmzmmopx 6a5a099f d2 | d2 1968 Parent commit (@-) : xznxytkn 0f21c5e1 d1 | d1 1969 Parent commit (@-) : sryyqqkq 44f57f24 a1 1970 Parent commit (@-) : pxnqtknr bcee4b60 b1 1971 Added 3 files, modified 0 files, removed 0 files 1972 [EOF] 1973 "); 1974 insta::assert_snapshot!(get_log_output(&work_dir), @r" 1975 @ 6a5a099f8a03 d2 1976 ├─┬─╮ 1977 │ │ ○ bcee4b6058e4 b1 1978 │ ○ │ 44f57f247bf2 a1 1979 │ ├─╯ 1980 ○ │ 0f21c5e185c5 d1 1981 │ │ ○ 09560d60cac4 c2 1982 │ ├─╯ 1983 │ ○ b27346e9a9bd c1 1984 ├─╯ 1985 │ ○ 7b44470918f4 b2 1986 │ ○ dcc98bc8bbea b1 1987 ├─╯ 1988 │ ○ 196bc1f0efc1 a4 1989 │ ○ 17072aa2b823 a3 1990 │ ○ 47df67757a64 a2 1991 │ ○ 9e85a474f005 a1 1992 ├─╯ 1993 ◆ 000000000000 1994 [EOF] 1995 "); 1996 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 1997 1998 // Duplicate multiple commits without a direct ancestry relationship between a 1999 // commit which is an ancestor of one of the duplicated commits and a commit 2000 // with no direct relationship. 2001 let output = work_dir.run_jj(["duplicate", "a3", "b1", "--after", "a2", "--before", "c2"]); 2002 insta::assert_snapshot!(output, @r" 2003 ------- stderr ------- 2004 Duplicated 17072aa2b823 as pyoswmwk 0d11d466 a3 2005 Duplicated dcc98bc8bbea as yqnpwwmq c32d1ccc b1 2006 Rebased 1 commits onto duplicated commits 2007 [EOF] 2008 "); 2009 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2010 @ 0cdd923e993a d2 2011 ○ 0f21c5e185c5 d1 2012 │ ○ 9feaad4c40f3 c2 2013 │ ├─┬─╮ 2014 │ │ │ ○ c32d1ccc8d5b b1 2015 │ │ ○ │ 0d11d4667aa9 a3 2016 │ │ ├─╯ 2017 │ ○ │ b27346e9a9bd c1 2018 ├─╯ │ 2019 │ ○ │ 7b44470918f4 b2 2020 │ ○ │ dcc98bc8bbea b1 2021 ├─╯ │ 2022 │ ○ │ 196bc1f0efc1 a4 2023 │ ○ │ 17072aa2b823 a3 2024 │ ├─╯ 2025 │ ○ 47df67757a64 a2 2026 │ ○ 9e85a474f005 a1 2027 ├─╯ 2028 ◆ 000000000000 2029 [EOF] 2030 "); 2031 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2032 2033 // Duplicate multiple commits without a direct ancestry relationship between a 2034 // commit which is a descendant of one of the duplicated commits and a 2035 // commit with no direct relationship. 2036 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--after", "a3", "--before", "c2"]); 2037 insta::assert_snapshot!(output, @r" 2038 ------- stderr ------- 2039 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 2040 Duplicated 9e85a474f005 as tpmlxquz 213aff50 (empty) a1 2041 Duplicated dcc98bc8bbea as uukzylyy 67b82bab b1 2042 Rebased 1 commits onto duplicated commits 2043 [EOF] 2044 "); 2045 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2046 @ 0cdd923e993a d2 2047 ○ 0f21c5e185c5 d1 2048 │ ○ 7c6622beae40 c2 2049 │ ├─┬─╮ 2050 │ │ │ ○ 67b82babd5f6 b1 2051 │ │ ○ │ 213aff50a82b a1 2052 │ │ ├─╯ 2053 │ ○ │ b27346e9a9bd c1 2054 ├─╯ │ 2055 │ ○ │ 7b44470918f4 b2 2056 │ ○ │ dcc98bc8bbea b1 2057 ├─╯ │ 2058 │ ○ │ 196bc1f0efc1 a4 2059 │ ├─╯ 2060 │ ○ 17072aa2b823 a3 2061 │ ○ 47df67757a64 a2 2062 │ ○ 9e85a474f005 a1 2063 ├─╯ 2064 ◆ 000000000000 2065 [EOF] 2066 "); 2067 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2068 2069 // Duplicate multiple commits without a direct ancestry relationship between 2070 // commits without a direct relationship to the duplicated commits. 2071 let output = work_dir.run_jj(["duplicate", "a1", "b1", "--after", "c1", "--before", "d2"]); 2072 insta::assert_snapshot!(output, @r" 2073 ------- stderr ------- 2074 Duplicated 9e85a474f005 as knltnxnu a2d38733 a1 2075 Duplicated dcc98bc8bbea as krtqozmx 2512c935 b1 2076 Rebased 1 commits onto duplicated commits 2077 Working copy (@) now at: nmzmmopx 4678ad48 d2 | d2 2078 Parent commit (@-) : xznxytkn 0f21c5e1 d1 | d1 2079 Parent commit (@-) : knltnxnu a2d38733 a1 2080 Parent commit (@-) : krtqozmx 2512c935 b1 2081 Added 3 files, modified 0 files, removed 0 files 2082 [EOF] 2083 "); 2084 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2085 @ 4678ad489eeb d2 2086 ├─┬─╮ 2087 │ │ ○ 2512c9358cb7 b1 2088 │ ○ │ a2d387331978 a1 2089 │ ├─╯ 2090 ○ │ 0f21c5e185c5 d1 2091 │ │ ○ 09560d60cac4 c2 2092 │ ├─╯ 2093 │ ○ b27346e9a9bd c1 2094 ├─╯ 2095 │ ○ 7b44470918f4 b2 2096 │ ○ dcc98bc8bbea b1 2097 ├─╯ 2098 │ ○ 196bc1f0efc1 a4 2099 │ ○ 17072aa2b823 a3 2100 │ ○ 47df67757a64 a2 2101 │ ○ 9e85a474f005 a1 2102 ├─╯ 2103 ◆ 000000000000 2104 [EOF] 2105 "); 2106 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2107 2108 // Duplicate multiple commits with an ancestry relationship between 2109 // commits without a direct relationship to the duplicated commits. 2110 let output = work_dir.run_jj(["duplicate", "a1", "a3", "--after", "c1", "--before", "d2"]); 2111 insta::assert_snapshot!(output, @r" 2112 ------- stderr ------- 2113 Duplicated 9e85a474f005 as wxzmtyol 893a647a a1 2114 Duplicated 17072aa2b823 as musouqkq fb14bc1e a3 2115 Rebased 1 commits onto duplicated commits 2116 Working copy (@) now at: nmzmmopx 21321795 d2 | d2 2117 Parent commit (@-) : xznxytkn 0f21c5e1 d1 | d1 2118 Parent commit (@-) : musouqkq fb14bc1e a3 2119 Added 3 files, modified 0 files, removed 0 files 2120 [EOF] 2121 "); 2122 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2123 @ 21321795f72f d2 2124 ├─╮ 2125 │ ○ fb14bc1e2c3c a3 2126 │ ○ 893a647a7f64 a1 2127 ○ │ 0f21c5e185c5 d1 2128 │ │ ○ 09560d60cac4 c2 2129 │ ├─╯ 2130 │ ○ b27346e9a9bd c1 2131 ├─╯ 2132 │ ○ 7b44470918f4 b2 2133 │ ○ dcc98bc8bbea b1 2134 ├─╯ 2135 │ ○ 196bc1f0efc1 a4 2136 │ ○ 17072aa2b823 a3 2137 │ ○ 47df67757a64 a2 2138 │ ○ 9e85a474f005 a1 2139 ├─╯ 2140 ◆ 000000000000 2141 [EOF] 2142 "); 2143 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2144 2145 // Duplicate multiple commits with an ancestry relationship between a commit 2146 // which is an ancestor of one of the duplicated commits and a commit 2147 // without a direct relationship. 2148 let output = work_dir.run_jj(["duplicate", "a3", "a4", "--after", "a2", "--before", "c2"]); 2149 insta::assert_snapshot!(output, @r" 2150 ------- stderr ------- 2151 Duplicated 17072aa2b823 as quyylypw d4d3c907 a3 2152 Duplicated 196bc1f0efc1 as prukwozq 96798f1b a4 2153 Rebased 1 commits onto duplicated commits 2154 [EOF] 2155 "); 2156 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2157 @ 0cdd923e993a d2 2158 ○ 0f21c5e185c5 d1 2159 │ ○ 267f3c6f05a2 c2 2160 │ ├─╮ 2161 │ │ ○ 96798f1b59fc a4 2162 │ │ ○ d4d3c9073a3b a3 2163 │ ○ │ b27346e9a9bd c1 2164 ├─╯ │ 2165 │ ○ │ 7b44470918f4 b2 2166 │ ○ │ dcc98bc8bbea b1 2167 ├─╯ │ 2168 │ ○ │ 196bc1f0efc1 a4 2169 │ ○ │ 17072aa2b823 a3 2170 │ ├─╯ 2171 │ ○ 47df67757a64 a2 2172 │ ○ 9e85a474f005 a1 2173 ├─╯ 2174 ◆ 000000000000 2175 [EOF] 2176 "); 2177 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2178 2179 // Duplicate multiple commits with an ancestry relationship between a commit 2180 // which is a a descendant of one of the duplicated commits and a commit 2181 // with no direct relationship. 2182 let output = work_dir.run_jj(["duplicate", "a1", "a2", "--before", "a3", "--after", "c2"]); 2183 insta::assert_snapshot!(output, @r" 2184 ------- stderr ------- 2185 Duplicated 9e85a474f005 as vvvtksvt b44d23b4 a1 2186 Duplicated 47df67757a64 as yvrnrpnw 4d0d41e2 a2 2187 Rebased 2 commits onto duplicated commits 2188 [EOF] 2189 "); 2190 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2191 @ 0cdd923e993a d2 2192 ○ 0f21c5e185c5 d1 2193 │ ○ 1ed8f9907f23 a4 2194 │ ○ c48cf7ac619c a3 2195 │ ├─╮ 2196 │ │ ○ 4d0d41e2b74e a2 2197 │ │ ○ b44d23b4c98e a1 2198 │ │ ○ 09560d60cac4 c2 2199 │ │ ○ b27346e9a9bd c1 2200 ├───╯ 2201 │ ○ 47df67757a64 a2 2202 │ ○ 9e85a474f005 a1 2203 ├─╯ 2204 │ ○ 7b44470918f4 b2 2205 │ ○ dcc98bc8bbea b1 2206 ├─╯ 2207 ◆ 000000000000 2208 [EOF] 2209 "); 2210 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2211 2212 // Duplicate multiple commits with an ancestry relationship between descendant 2213 // commits. 2214 let output = work_dir.run_jj(["duplicate", "a3", "a4", "--after", "a1", "--before", "a2"]); 2215 insta::assert_snapshot!(output, @r" 2216 ------- stderr ------- 2217 Warning: Duplicating commit 196bc1f0efc1 as an ancestor of itself 2218 Warning: Duplicating commit 17072aa2b823 as an ancestor of itself 2219 Duplicated 17072aa2b823 as sukptuzs 8678104c a3 2220 Duplicated 196bc1f0efc1 as rxnrppxl b6580274 a4 2221 Rebased 3 commits onto duplicated commits 2222 [EOF] 2223 "); 2224 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2225 @ 0cdd923e993a d2 2226 ○ 0f21c5e185c5 d1 2227 │ ○ 09560d60cac4 c2 2228 │ ○ b27346e9a9bd c1 2229 ├─╯ 2230 │ ○ 7b44470918f4 b2 2231 │ ○ dcc98bc8bbea b1 2232 ├─╯ 2233 │ ○ 795c1625854d a4 2234 │ ○ c3fbe644a16b a3 2235 │ ○ af75098c676a a2 2236 │ ○ b6580274470b a4 2237 │ ○ 8678104c14af a3 2238 │ ○ 9e85a474f005 a1 2239 ├─╯ 2240 ◆ 000000000000 2241 [EOF] 2242 "); 2243 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2244 2245 // Duplicate multiple commits with an ancestry relationship between ancestor 2246 // commits. 2247 let output = work_dir.run_jj(["duplicate", "a1", "a2", "--after", "a3", "--before", "a4"]); 2248 insta::assert_snapshot!(output, @r" 2249 ------- stderr ------- 2250 Warning: Duplicating commit 47df67757a64 as a descendant of itself 2251 Warning: Duplicating commit 9e85a474f005 as a descendant of itself 2252 Duplicated 9e85a474f005 as rwkyzntp b68b9a00 (empty) a1 2253 Duplicated 47df67757a64 as nqtyztop 0dd00ded (empty) a2 2254 Rebased 1 commits onto duplicated commits 2255 [EOF] 2256 "); 2257 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2258 @ 0cdd923e993a d2 2259 ○ 0f21c5e185c5 d1 2260 │ ○ 09560d60cac4 c2 2261 │ ○ b27346e9a9bd c1 2262 ├─╯ 2263 │ ○ 7b44470918f4 b2 2264 │ ○ dcc98bc8bbea b1 2265 ├─╯ 2266 │ ○ 4f02390e56aa a4 2267 │ ○ 0dd00dedd0c5 a2 2268 │ ○ b68b9a0073cb a1 2269 │ ○ 17072aa2b823 a3 2270 │ ○ 47df67757a64 a2 2271 │ ○ 9e85a474f005 a1 2272 ├─╯ 2273 ◆ 000000000000 2274 [EOF] 2275 "); 2276 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2277 2278 // Duplicate multiple commits with an ancestry relationship between an ancestor 2279 // commit and a descendant commit. 2280 let output = work_dir.run_jj(["duplicate", "a2", "a3", "--after", "a1", "--before", "a4"]); 2281 insta::assert_snapshot!(output, @r" 2282 ------- stderr ------- 2283 Duplicated 47df67757a64 as nwmqwkzz 8517eaa7 a2 2284 Duplicated 17072aa2b823 as uwrrnrtx 3ce18231 a3 2285 Rebased 1 commits onto duplicated commits 2286 [EOF] 2287 "); 2288 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2289 @ 0cdd923e993a d2 2290 ○ 0f21c5e185c5 d1 2291 │ ○ 09560d60cac4 c2 2292 │ ○ b27346e9a9bd c1 2293 ├─╯ 2294 │ ○ 7b44470918f4 b2 2295 │ ○ dcc98bc8bbea b1 2296 ├─╯ 2297 │ ○ 0855137fa398 a4 2298 │ ├─╮ 2299 │ │ ○ 3ce182317a5b a3 2300 │ │ ○ 8517eaa73536 a2 2301 │ ○ │ 17072aa2b823 a3 2302 │ ○ │ 47df67757a64 a2 2303 │ ├─╯ 2304 │ ○ 9e85a474f005 a1 2305 ├─╯ 2306 ◆ 000000000000 2307 [EOF] 2308 "); 2309 work_dir.run_jj(["op", "restore", &setup_opid]).success(); 2310 2311 // Should error if a loop will be created. 2312 let output = work_dir.run_jj(["duplicate", "a1", "--after", "b2", "--before", "b1"]); 2313 insta::assert_snapshot!(output, @r" 2314 ------- stderr ------- 2315 Error: Refusing to create a loop: commit 7b44470918f4 would be both an ancestor and a descendant of the duplicated commits 2316 [EOF] 2317 [exit status: 1] 2318 "); 2319} 2320 2321// https://github.com/jj-vcs/jj/issues/1050 2322#[test] 2323fn test_undo_after_duplicate() { 2324 let test_env = TestEnvironment::default(); 2325 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 2326 let work_dir = test_env.work_dir("repo"); 2327 2328 create_commit(&work_dir, "a", &[]); 2329 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2330 @ 2443ea76b0b1 a 2331 ◆ 000000000000 2332 [EOF] 2333 "); 2334 2335 let output = work_dir.run_jj(["duplicate", "a"]); 2336 insta::assert_snapshot!(output, @r" 2337 ------- stderr ------- 2338 Duplicated 2443ea76b0b1 as mzvwutvl f5cefcbb a 2339 [EOF] 2340 "); 2341 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2342 @ 2443ea76b0b1 a 2343 │ ○ f5cefcbb65a4 a 2344 ├─╯ 2345 ◆ 000000000000 2346 [EOF] 2347 "); 2348 2349 let output = work_dir.run_jj(["undo"]); 2350 insta::assert_snapshot!(output, @r" 2351 ------- stderr ------- 2352 Undid operation: d64d953f7d2b (2001-02-03 08:05:11) duplicate 1 commit(s) 2353 [EOF] 2354 "); 2355 insta::assert_snapshot!(get_log_output(&work_dir), @r" 2356 @ 2443ea76b0b1 a 2357 ◆ 000000000000 2358 [EOF] 2359 "); 2360} 2361 2362// https://github.com/jj-vcs/jj/issues/694 2363#[test] 2364fn test_rebase_duplicates() { 2365 let test_env = TestEnvironment::default(); 2366 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 2367 let work_dir = test_env.work_dir("repo"); 2368 2369 create_commit(&work_dir, "a", &[]); 2370 create_commit(&work_dir, "b", &["a"]); 2371 create_commit(&work_dir, "c", &["b"]); 2372 // Test the setup 2373 insta::assert_snapshot!(get_log_output_with_ts(&work_dir), @r" 2374 @ 7e4fbf4f2759 c @ 2001-02-03 04:05:13.000 +07:00 2375 ○ 1394f625cbbd b @ 2001-02-03 04:05:11.000 +07:00 2376 ○ 2443ea76b0b1 a @ 2001-02-03 04:05:09.000 +07:00 2377 ◆ 000000000000 @ 1970-01-01 00:00:00.000 +00:00 2378 [EOF] 2379 "); 2380 2381 let output = work_dir.run_jj(["duplicate", "c"]); 2382 insta::assert_snapshot!(output, @r" 2383 ------- stderr ------- 2384 Duplicated 7e4fbf4f2759 as yostqsxw 0ac2063b c 2385 [EOF] 2386 "); 2387 let output = work_dir.run_jj(["duplicate", "c"]); 2388 insta::assert_snapshot!(output, @r" 2389 ------- stderr ------- 2390 Duplicated 7e4fbf4f2759 as znkkpsqq ce5f4eeb c 2391 [EOF] 2392 "); 2393 insta::assert_snapshot!(get_log_output_with_ts(&work_dir), @r" 2394 @ 7e4fbf4f2759 c @ 2001-02-03 04:05:13.000 +07:00 2395 │ ○ ce5f4eeb69d1 c @ 2001-02-03 04:05:16.000 +07:00 2396 ├─╯ 2397 │ ○ 0ac2063b1bee c @ 2001-02-03 04:05:15.000 +07:00 2398 ├─╯ 2399 ○ 1394f625cbbd b @ 2001-02-03 04:05:11.000 +07:00 2400 ○ 2443ea76b0b1 a @ 2001-02-03 04:05:09.000 +07:00 2401 ◆ 000000000000 @ 1970-01-01 00:00:00.000 +00:00 2402 [EOF] 2403 "); 2404 2405 let output = work_dir.run_jj(["rebase", "-s", "b", "-d", "root()"]); 2406 insta::assert_snapshot!(output, @r" 2407 ------- stderr ------- 2408 Rebased 4 commits onto destination 2409 Working copy (@) now at: royxmykx ed671a3c c | c 2410 Parent commit (@-) : zsuskuln 4c6f1569 b | b 2411 Added 0 files, modified 0 files, removed 1 files 2412 [EOF] 2413 "); 2414 // Some of the duplicate commits' timestamps were changed a little to make them 2415 // have distinct commit ids. 2416 insta::assert_snapshot!(get_log_output_with_ts(&work_dir), @r" 2417 @ ed671a3cbf35 c @ 2001-02-03 04:05:18.000 +07:00 2418 │ ○ b86e9f27d085 c @ 2001-02-03 04:05:16.000 +07:00 2419 ├─╯ 2420 │ ○ 8033590fe04d c @ 2001-02-03 04:05:17.000 +07:00 2421 ├─╯ 2422 ○ 4c6f1569e2a9 b @ 2001-02-03 04:05:18.000 +07:00 2423 │ ○ 2443ea76b0b1 a @ 2001-02-03 04:05:09.000 +07:00 2424 ├─╯ 2425 ◆ 000000000000 @ 1970-01-01 00:00:00.000 +00:00 2426 [EOF] 2427 "); 2428} 2429 2430#[must_use] 2431fn get_log_output(work_dir: &TestWorkDir) -> CommandOutput { 2432 let template = r#"commit_id.short() ++ " " ++ description.first_line()"#; 2433 work_dir.run_jj(["log", "-T", template]) 2434} 2435 2436#[must_use] 2437fn get_log_output_with_ts(work_dir: &TestWorkDir) -> CommandOutput { 2438 let template = r#" 2439 commit_id.short() ++ " " ++ description.first_line() ++ " @ " ++ committer.timestamp() 2440 "#; 2441 work_dir.run_jj(["log", "-T", template]) 2442}