just playing with tangled
at ig/vimdiffwarn 1049 lines 31 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::TestEnvironment; 16use crate::common::TestWorkDir; 17 18#[test] 19fn test_bookmark_names() { 20 let test_env = TestEnvironment::default(); 21 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 22 let work_dir = test_env.work_dir("repo"); 23 24 test_env.run_jj_in(".", ["git", "init", "origin"]).success(); 25 let origin_dir = test_env.work_dir("origin"); 26 let origin_git_repo_path = origin_dir 27 .root() 28 .join(".jj") 29 .join("repo") 30 .join("store") 31 .join("git"); 32 33 work_dir 34 .run_jj(["bookmark", "create", "-r@", "aaa-local"]) 35 .success(); 36 work_dir 37 .run_jj(["bookmark", "create", "-r@", "bbb-local"]) 38 .success(); 39 40 // add various remote branches 41 work_dir 42 .run_jj([ 43 "git", 44 "remote", 45 "add", 46 "origin", 47 origin_git_repo_path.to_str().unwrap(), 48 ]) 49 .success(); 50 work_dir 51 .run_jj(["bookmark", "create", "-r@", "aaa-tracked"]) 52 .success(); 53 work_dir 54 .run_jj(["desc", "-r", "aaa-tracked", "-m", "x"]) 55 .success(); 56 work_dir 57 .run_jj(["bookmark", "create", "-r@", "bbb-tracked"]) 58 .success(); 59 work_dir 60 .run_jj(["desc", "-r", "bbb-tracked", "-m", "x"]) 61 .success(); 62 work_dir 63 .run_jj(["git", "push", "--allow-new", "--bookmark", "glob:*-tracked"]) 64 .success(); 65 66 origin_dir 67 .run_jj(["bookmark", "create", "-r@", "aaa-untracked"]) 68 .success(); 69 origin_dir 70 .run_jj(["desc", "-r", "aaa-untracked", "-m", "x"]) 71 .success(); 72 origin_dir 73 .run_jj(["bookmark", "create", "-r@", "bbb-untracked"]) 74 .success(); 75 origin_dir 76 .run_jj(["desc", "-r", "bbb-untracked", "-m", "x"]) 77 .success(); 78 origin_dir.run_jj(["git", "export"]).success(); 79 work_dir.run_jj(["git", "fetch"]).success(); 80 81 let mut test_env = test_env; 82 // Every shell hook is a little different, e.g. the zsh hooks add some 83 // additional environment variables. But this is irrelevant for the purpose 84 // of testing our own logic, so it's fine to test a single shell only. 85 test_env.add_env_var("COMPLETE", "fish"); 86 let test_env = test_env; 87 let work_dir = test_env.work_dir("repo"); 88 89 let output = work_dir.run_jj(["--", "jj", "bookmark", "rename", ""]); 90 insta::assert_snapshot!(output, @r" 91 aaa-local x 92 aaa-tracked x 93 bbb-local x 94 bbb-tracked x 95 --repository Path to repository to operate on 96 --ignore-working-copy Don't snapshot the working copy, and don't update it 97 --ignore-immutable Allow rewriting immutable commits 98 --at-operation Operation to load the repo at 99 --debug Enable debug logging 100 --color When to colorize output 101 --quiet Silence non-primary command output 102 --no-pager Disable the pager 103 --config Additional configuration options (can be repeated) 104 --config-file Additional configuration files (can be repeated) 105 --help Print help (see more with '--help') 106 [EOF] 107 "); 108 109 let output = work_dir.run_jj(["--", "jj", "bookmark", "rename", "a"]); 110 insta::assert_snapshot!(output, @r" 111 aaa-local x 112 aaa-tracked x 113 [EOF] 114 "); 115 116 let output = work_dir.run_jj(["--", "jj", "bookmark", "delete", "a"]); 117 insta::assert_snapshot!(output, @r" 118 aaa-local x 119 aaa-tracked x 120 [EOF] 121 "); 122 123 let output = work_dir.run_jj(["--", "jj", "bookmark", "forget", "a"]); 124 insta::assert_snapshot!(output, @r" 125 aaa-local x 126 aaa-tracked x 127 aaa-untracked 128 [EOF] 129 "); 130 131 let output = work_dir.run_jj(["--", "jj", "bookmark", "list", "--bookmark", "a"]); 132 insta::assert_snapshot!(output, @r" 133 aaa-local x 134 aaa-tracked x 135 aaa-untracked 136 [EOF] 137 "); 138 139 let output = work_dir.run_jj(["--", "jj", "bookmark", "move", "a"]); 140 insta::assert_snapshot!(output, @r" 141 aaa-local x 142 aaa-tracked x 143 [EOF] 144 "); 145 146 let output = work_dir.run_jj(["--", "jj", "bookmark", "set", "a"]); 147 insta::assert_snapshot!(output, @r" 148 aaa-local x 149 aaa-tracked x 150 [EOF] 151 "); 152 153 let output = work_dir.run_jj(["--", "jj", "bookmark", "track", "a"]); 154 insta::assert_snapshot!(output, @r" 155 aaa-untracked@origin x 156 [EOF] 157 "); 158 159 let output = work_dir.run_jj(["--", "jj", "bookmark", "untrack", "a"]); 160 insta::assert_snapshot!(output, @r" 161 aaa-tracked@origin x 162 [EOF] 163 "); 164 165 let output = work_dir.run_jj(["--", "jj", "git", "push", "-b", "a"]); 166 insta::assert_snapshot!(output, @r" 167 aaa-local x 168 aaa-tracked x 169 [EOF] 170 "); 171 172 let output = work_dir.run_jj(["--", "jj", "git", "fetch", "-b", "a"]); 173 insta::assert_snapshot!(output, @r" 174 aaa-local x 175 aaa-tracked x 176 aaa-untracked 177 [EOF] 178 "); 179} 180 181#[test] 182fn test_global_arg_repository_is_respected() { 183 let test_env = TestEnvironment::default(); 184 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 185 let work_dir = test_env.work_dir("repo"); 186 187 work_dir 188 .run_jj(["bookmark", "create", "-r@", "aaa"]) 189 .success(); 190 191 let mut test_env = test_env; 192 test_env.add_env_var("COMPLETE", "fish"); 193 let test_env = test_env; 194 195 let output = test_env.run_jj_in( 196 ".", 197 [ 198 "--", 199 "jj", 200 "--repository", 201 "repo", 202 "bookmark", 203 "rename", 204 "a", 205 ], 206 ); 207 insta::assert_snapshot!(output, @r" 208 aaa (no description set) 209 [EOF] 210 "); 211} 212 213#[test] 214fn test_aliases_are_resolved() { 215 let test_env = TestEnvironment::default(); 216 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 217 let work_dir = test_env.work_dir("repo"); 218 219 work_dir 220 .run_jj(["bookmark", "create", "-r@", "aaa"]) 221 .success(); 222 223 // user config alias 224 test_env.add_config(r#"aliases.b = ["bookmark"]"#); 225 // repo config alias 226 work_dir 227 .run_jj(["config", "set", "--repo", "aliases.b2", "['bookmark']"]) 228 .success(); 229 230 let mut test_env = test_env; 231 test_env.add_env_var("COMPLETE", "fish"); 232 let test_env = test_env; 233 let work_dir = test_env.work_dir("repo"); 234 235 let output = work_dir.run_jj(["--", "jj", "b", "rename", "a"]); 236 insta::assert_snapshot!(output, @r" 237 aaa (no description set) 238 [EOF] 239 "); 240 241 let output = work_dir.run_jj(["--", "jj", "b2", "rename", "a"]); 242 insta::assert_snapshot!(output, @r" 243 aaa (no description set) 244 [EOF] 245 "); 246} 247 248#[test] 249fn test_completions_are_generated() { 250 let mut test_env = TestEnvironment::default(); 251 test_env.add_env_var("COMPLETE", "fish"); 252 let mut insta_settings = insta::Settings::clone_current(); 253 insta_settings.add_filter(r"(--arguments) .*", "$1 .."); // omit path to jj binary 254 let _guard = insta_settings.bind_to_scope(); 255 256 let output = test_env.run_jj_in(".", [""; 0]); 257 insta::assert_snapshot!(output, @r" 258 complete --keep-order --exclusive --command jj --arguments .. 259 [EOF] 260 "); 261 let output = test_env.run_jj_in(".", ["--"]); 262 insta::assert_snapshot!(output, @r" 263 complete --keep-order --exclusive --command jj --arguments .. 264 [EOF] 265 "); 266} 267 268#[test] 269fn test_zsh_completion() { 270 let mut test_env = TestEnvironment::default(); 271 test_env.add_env_var("COMPLETE", "zsh"); 272 273 // ["--", "jj"] 274 // ^^^^ index = 0 275 let complete_at = |index: usize, args: &[&str]| { 276 test_env.run_jj_with(|cmd| { 277 cmd.args(args) 278 .env("_CLAP_COMPLETE_INDEX", index.to_string()) 279 }) 280 }; 281 282 // Command names should be suggested. If the default command were expanded, 283 // only "log" would be listed. 284 let output = complete_at(1, &["--", "jj"]); 285 insta::assert_snapshot!( 286 output.normalize_stdout_with(|s| s.split_inclusive('\n').take(2).collect()), @r" 287 abandon:Abandon a revision 288 absorb:Move changes from a revision into the stack of mutable revisions 289 [EOF] 290 "); 291 let output = complete_at(2, &["--", "jj", "--no-pager"]); 292 insta::assert_snapshot!( 293 output.normalize_stdout_with(|s| s.split_inclusive('\n').take(2).collect()), @r" 294 abandon:Abandon a revision 295 absorb:Move changes from a revision into the stack of mutable revisions 296 [EOF] 297 "); 298 299 let output = complete_at(1, &["--", "jj", "b"]); 300 insta::assert_snapshot!(output, @"bookmark:Manage bookmarks [default alias: b][EOF]"); 301} 302 303#[test] 304fn test_remote_names() { 305 let mut test_env = TestEnvironment::default(); 306 test_env.run_jj_in(".", ["git", "init"]).success(); 307 308 test_env 309 .run_jj_in( 310 ".", 311 ["git", "remote", "add", "origin", "git@git.local:user/repo"], 312 ) 313 .success(); 314 315 test_env.add_env_var("COMPLETE", "fish"); 316 317 let output = test_env.run_jj_in(".", ["--", "jj", "git", "remote", "remove", "o"]); 318 insta::assert_snapshot!(output, @r" 319 origin 320 [EOF] 321 "); 322 323 let output = test_env.run_jj_in(".", ["--", "jj", "git", "remote", "rename", "o"]); 324 insta::assert_snapshot!(output, @r" 325 origin 326 [EOF] 327 "); 328 329 let output = test_env.run_jj_in(".", ["--", "jj", "git", "remote", "set-url", "o"]); 330 insta::assert_snapshot!(output, @r" 331 origin 332 [EOF] 333 "); 334 335 let output = test_env.run_jj_in(".", ["--", "jj", "git", "push", "--remote", "o"]); 336 insta::assert_snapshot!(output, @r" 337 origin 338 [EOF] 339 "); 340 341 let output = test_env.run_jj_in(".", ["--", "jj", "git", "fetch", "--remote", "o"]); 342 insta::assert_snapshot!(output, @r" 343 origin 344 [EOF] 345 "); 346 347 let output = test_env.run_jj_in(".", ["--", "jj", "bookmark", "list", "--remote", "o"]); 348 insta::assert_snapshot!(output, @r" 349 origin 350 [EOF] 351 "); 352} 353 354#[test] 355fn test_aliases_are_completed() { 356 let test_env = TestEnvironment::default(); 357 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 358 let work_dir = test_env.work_dir("repo"); 359 360 // user config alias 361 test_env.add_config(r#"aliases.user-alias = ["bookmark"]"#); 362 // repo config alias 363 work_dir 364 .run_jj([ 365 "config", 366 "set", 367 "--repo", 368 "aliases.repo-alias", 369 "['bookmark']", 370 ]) 371 .success(); 372 373 let mut test_env = test_env; 374 test_env.add_env_var("COMPLETE", "fish"); 375 let test_env = test_env; 376 let work_dir = test_env.work_dir("repo"); 377 378 let output = work_dir.run_jj(["--", "jj", "user-al"]); 379 insta::assert_snapshot!(output, @r" 380 user-alias 381 [EOF] 382 "); 383 384 // make sure --repository flag is respected 385 let output = test_env.run_jj_in( 386 ".", 387 [ 388 "--", 389 "jj", 390 "--repository", 391 work_dir.root().to_str().unwrap(), 392 "repo-al", 393 ], 394 ); 395 insta::assert_snapshot!(output, @r" 396 repo-alias 397 [EOF] 398 "); 399 400 // cannot load aliases from --config flag 401 let output = test_env.run_jj_in( 402 ".", 403 [ 404 "--", 405 "jj", 406 "--config=aliases.cli-alias=['bookmark']", 407 "cli-al", 408 ], 409 ); 410 insta::assert_snapshot!(output, @""); 411} 412 413#[test] 414fn test_revisions() { 415 let test_env = TestEnvironment::default(); 416 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 417 let work_dir = test_env.work_dir("repo"); 418 419 // create remote to test remote branches 420 test_env.run_jj_in(".", ["git", "init", "origin"]).success(); 421 let origin_dir = test_env.work_dir("origin"); 422 let origin_git_repo_path = origin_dir 423 .root() 424 .join(".jj") 425 .join("repo") 426 .join("store") 427 .join("git"); 428 work_dir 429 .run_jj([ 430 "git", 431 "remote", 432 "add", 433 "origin", 434 origin_git_repo_path.to_str().unwrap(), 435 ]) 436 .success(); 437 origin_dir 438 .run_jj(["b", "c", "-r@", "remote_bookmark"]) 439 .success(); 440 origin_dir 441 .run_jj(["commit", "-m", "remote_commit"]) 442 .success(); 443 origin_dir.run_jj(["git", "export"]).success(); 444 work_dir.run_jj(["git", "fetch"]).success(); 445 446 work_dir 447 .run_jj(["b", "c", "-r@", "immutable_bookmark"]) 448 .success(); 449 work_dir.run_jj(["commit", "-m", "immutable"]).success(); 450 test_env.add_config(r#"revset-aliases."immutable_heads()" = "immutable_bookmark""#); 451 test_env.add_config(r#"revset-aliases."siblings" = "@-+ ~@""#); 452 test_env.add_config( 453 r#"revset-aliases."alias_with_newline" = ''' 454 roots( 455 conflicts() 456 ) 457 '''"#, 458 ); 459 460 work_dir 461 .run_jj(["b", "c", "-r@", "mutable_bookmark"]) 462 .success(); 463 work_dir.run_jj(["commit", "-m", "mutable"]).success(); 464 465 work_dir 466 .run_jj(["describe", "-m", "working_copy"]) 467 .success(); 468 469 let mut test_env = test_env; 470 test_env.add_env_var("COMPLETE", "fish"); 471 let test_env = test_env; 472 let work_dir = test_env.work_dir("repo"); 473 474 // There are _a lot_ of commands and arguments accepting revisions. 475 // Let's not test all of them. Having at least one test per variation of 476 // completion function should be sufficient. 477 478 // complete all revisions 479 let output = work_dir.run_jj(["--", "jj", "diff", "--from", ""]); 480 insta::assert_snapshot!(output, @r" 481 immutable_bookmark immutable 482 mutable_bookmark mutable 483 k working_copy 484 y mutable 485 q immutable 486 zq remote_commit 487 zz (no description set) 488 remote_bookmark@origin remote_commit 489 alias_with_newline roots( 490 siblings @-+ ~@ 491 [EOF] 492 "); 493 494 // complete only mutable revisions 495 let output = work_dir.run_jj(["--", "jj", "squash", "--into", ""]); 496 insta::assert_snapshot!(output, @r" 497 mutable_bookmark mutable 498 k working_copy 499 y mutable 500 zq remote_commit 501 alias_with_newline roots( 502 siblings @-+ ~@ 503 [EOF] 504 "); 505 506 // complete args of the default command 507 test_env.add_config("ui.default-command = 'log'"); 508 let output = work_dir.run_jj(["--", "jj", "-r", ""]); 509 insta::assert_snapshot!(output, @r" 510 immutable_bookmark immutable 511 mutable_bookmark mutable 512 k working_copy 513 y mutable 514 q immutable 515 zq remote_commit 516 zz (no description set) 517 remote_bookmark@origin remote_commit 518 alias_with_newline roots( 519 siblings @-+ ~@ 520 [EOF] 521 "); 522 523 // Begin testing `jj git push --named` 524 525 // The name of a bookmark does not get completed, since we want to create a new 526 // bookmark 527 let output = work_dir.run_jj(["--", "jj", "git", "push", "--named", ""]); 528 insta::assert_snapshot!(output, @""); 529 let output = work_dir.run_jj(["--", "jj", "git", "push", "--named", "a"]); 530 insta::assert_snapshot!(output, @""); 531 532 let output = work_dir.run_jj(["--", "jj", "git", "push", "--named", "a="]); 533 insta::assert_snapshot!(output, @r" 534 a=immutable_bookmark immutable 535 a=mutable_bookmark mutable 536 a=k working_copy 537 a=y mutable 538 a=q immutable 539 a=zq remote_commit 540 a=zz (no description set) 541 a=remote_bookmark@origin remote_commit 542 a=alias_with_newline roots( 543 a=siblings @-+ ~@ 544 [EOF] 545 "); 546 547 let output = work_dir.run_jj(["--", "jj", "git", "push", "--named", "a=a"]); 548 insta::assert_snapshot!(output, @r" 549 a=alias_with_newline roots( 550 [EOF] 551 "); 552} 553 554#[test] 555fn test_operations() { 556 let test_env = TestEnvironment::default(); 557 558 // suppress warnings on stderr of completions for invalid args 559 test_env.add_config("ui.default-command = 'log'"); 560 561 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 562 let work_dir = test_env.work_dir("repo"); 563 work_dir 564 .run_jj(["describe", "-m", "description 0"]) 565 .success(); 566 work_dir 567 .run_jj(["describe", "-m", "description 1"]) 568 .success(); 569 work_dir 570 .run_jj(["describe", "-m", "description 2"]) 571 .success(); 572 work_dir 573 .run_jj(["describe", "-m", "description 3"]) 574 .success(); 575 work_dir 576 .run_jj(["describe", "-m", "description 4"]) 577 .success(); 578 579 let mut test_env = test_env; 580 test_env.add_env_var("COMPLETE", "fish"); 581 let test_env = test_env; 582 let work_dir = test_env.work_dir("repo"); 583 584 let output = work_dir.run_jj(["--", "jj", "op", "show", ""]).success(); 585 let add_workspace_id = output 586 .stdout 587 .raw() 588 .lines() 589 .nth(5) 590 .unwrap() 591 .split('\t') 592 .next() 593 .unwrap(); 594 insta::assert_snapshot!(add_workspace_id, @"eac759b9ab75"); 595 596 let output = work_dir.run_jj(["--", "jj", "op", "show", "5"]); 597 insta::assert_snapshot!(output, @r" 598 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 599 518b588abbc6 (2001-02-03 08:05:09) describe commit 19611c995a342c01f525583e5fcafdd211f6d009 600 [EOF] 601 "); 602 // make sure global --at-op flag is respected 603 let output = work_dir.run_jj(["--", "jj", "--at-op", "518b588abbc6", "op", "show", "5"]); 604 insta::assert_snapshot!(output, @r" 605 518b588abbc6 (2001-02-03 08:05:09) describe commit 19611c995a342c01f525583e5fcafdd211f6d009 606 [EOF] 607 "); 608 609 let output = work_dir.run_jj(["--", "jj", "--at-op", "5b"]); 610 insta::assert_snapshot!(output, @r" 611 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 612 [EOF] 613 "); 614 615 let output = work_dir.run_jj(["--", "jj", "op", "abandon", "5b"]); 616 insta::assert_snapshot!(output, @r" 617 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 618 [EOF] 619 "); 620 621 let output = work_dir.run_jj(["--", "jj", "op", "diff", "--op", "5b"]); 622 insta::assert_snapshot!(output, @r" 623 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 624 [EOF] 625 "); 626 let output = work_dir.run_jj(["--", "jj", "op", "diff", "--from", "5b"]); 627 insta::assert_snapshot!(output, @r" 628 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 629 [EOF] 630 "); 631 let output = work_dir.run_jj(["--", "jj", "op", "diff", "--to", "5b"]); 632 insta::assert_snapshot!(output, @r" 633 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 634 [EOF] 635 "); 636 637 let output = work_dir.run_jj(["--", "jj", "op", "restore", "5b"]); 638 insta::assert_snapshot!(output, @r" 639 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 640 [EOF] 641 "); 642 643 let output = work_dir.run_jj(["--", "jj", "op", "undo", "5b"]); 644 insta::assert_snapshot!(output, @r" 645 5bbb4ca536a8 (2001-02-03 08:05:12) describe commit 968261075dddabf4b0e333c1cc9a49ce26a3f710 646 [EOF] 647 "); 648} 649 650#[test] 651fn test_workspaces() { 652 let test_env = TestEnvironment::default(); 653 test_env.run_jj_in(".", ["git", "init", "main"]).success(); 654 let main_dir = test_env.work_dir("main"); 655 656 main_dir.write_file("file", "contents"); 657 main_dir.run_jj(["describe", "-m", "initial"]).success(); 658 659 // same prefix as "default" workspace 660 main_dir 661 .run_jj(["workspace", "add", "--name", "def-second", "../secondary"]) 662 .success(); 663 664 let mut test_env = test_env; 665 test_env.add_env_var("COMPLETE", "fish"); 666 let test_env = test_env; 667 let main_dir = test_env.work_dir("main"); 668 669 let output = main_dir.run_jj(["--", "jj", "workspace", "forget", "def"]); 670 insta::assert_snapshot!(output, @r" 671 def-second (no description set) 672 default initial 673 [EOF] 674 "); 675} 676 677#[test] 678fn test_config() { 679 let mut test_env = TestEnvironment::default(); 680 test_env.add_env_var("COMPLETE", "fish"); 681 let dir = test_env.env_root(); 682 683 let output = test_env.run_jj_in(dir, ["--", "jj", "config", "get", "c"]); 684 insta::assert_snapshot!(output, @r" 685 core.fsmonitor Whether to use an external filesystem monitor, useful for large repos 686 core.watchman.register-snapshot-trigger Whether to use triggers to monitor for changes in the background. 687 [EOF] 688 "); 689 690 let output = test_env.run_jj_in(dir, ["--", "jj", "config", "list", "c"]); 691 insta::assert_snapshot!(output, @r" 692 colors Mapping from jj formatter labels to colors 693 core 694 core.fsmonitor Whether to use an external filesystem monitor, useful for large repos 695 core.watchman 696 core.watchman.register-snapshot-trigger Whether to use triggers to monitor for changes in the background. 697 [EOF] 698 "); 699 700 let output = test_env.run_jj_in(dir, ["--", "jj", "log", "--config", "c"]); 701 insta::assert_snapshot!(output, @r" 702 core.fsmonitor= Whether to use an external filesystem monitor, useful for large repos 703 core.watchman.register-snapshot-trigger= Whether to use triggers to monitor for changes in the background. 704 [EOF] 705 "); 706 707 let output = test_env.run_jj_in( 708 dir, 709 ["--", "jj", "log", "--config", "ui.conflict-marker-style="], 710 ); 711 insta::assert_snapshot!(output, @r" 712 ui.conflict-marker-style=diff 713 ui.conflict-marker-style=snapshot 714 ui.conflict-marker-style=git 715 [EOF] 716 "); 717 let output = test_env.run_jj_in( 718 dir, 719 ["--", "jj", "log", "--config", "ui.conflict-marker-style=g"], 720 ); 721 insta::assert_snapshot!(output, @r" 722 ui.conflict-marker-style=git 723 [EOF] 724 "); 725 726 let output = test_env.run_jj_in( 727 dir, 728 [ 729 "--", 730 "jj", 731 "log", 732 "--config", 733 "git.abandon-unreachable-commits=", 734 ], 735 ); 736 insta::assert_snapshot!(output, @r" 737 git.abandon-unreachable-commits=false 738 git.abandon-unreachable-commits=true 739 [EOF] 740 "); 741} 742 743#[test] 744fn test_template_alias() { 745 let mut test_env = TestEnvironment::default(); 746 test_env.add_env_var("COMPLETE", "fish"); 747 let dir = test_env.env_root(); 748 749 let output = test_env.run_jj_in(dir, ["--", "jj", "log", "-T", ""]); 750 insta::assert_snapshot!(output, @r" 751 builtin_config_list 752 builtin_config_list_detailed 753 builtin_draft_commit_description 754 builtin_log_comfortable 755 builtin_log_compact 756 builtin_log_compact_full_description 757 builtin_log_detailed 758 builtin_log_node 759 builtin_log_node_ascii 760 builtin_log_oneline 761 builtin_op_log_comfortable 762 builtin_op_log_compact 763 builtin_op_log_node 764 builtin_op_log_node_ascii 765 builtin_op_log_oneline 766 commit_summary_separator 767 description_placeholder 768 email_placeholder 769 name_placeholder 770 [EOF] 771 "); 772} 773 774fn create_commit( 775 work_dir: &TestWorkDir, 776 name: &str, 777 parents: &[&str], 778 files: &[(&str, Option<&str>)], 779) { 780 let parents = match parents { 781 [] => &["root()"], 782 parents => parents, 783 }; 784 work_dir 785 .run_jj_with(|cmd| cmd.args(["new", "-m", name]).args(parents)) 786 .success(); 787 for (name, content) in files { 788 if let Some((dir, _)) = name.rsplit_once('/') { 789 work_dir.create_dir_all(dir); 790 } 791 match content { 792 Some(content) => work_dir.write_file(name, content), 793 None => work_dir.remove_file(name), 794 } 795 } 796 work_dir 797 .run_jj(["bookmark", "create", "-r@", name]) 798 .success(); 799} 800 801#[test] 802fn test_files() { 803 let test_env = TestEnvironment::default(); 804 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 805 let work_dir = test_env.work_dir("repo"); 806 807 create_commit( 808 &work_dir, 809 "first", 810 &[], 811 &[ 812 ("f_unchanged", Some("unchanged\n")), 813 ("f_modified", Some("not_yet_modified\n")), 814 ("f_not_yet_renamed", Some("renamed\n")), 815 ("f_deleted", Some("not_yet_deleted\n")), 816 // not yet: "added" file 817 ], 818 ); 819 create_commit( 820 &work_dir, 821 "second", 822 &["first"], 823 &[ 824 // "unchanged" file 825 ("f_modified", Some("modified\n")), 826 ("f_not_yet_renamed", None), 827 ("f_renamed", Some("renamed\n")), 828 ("f_deleted", None), 829 ("f_added", Some("added\n")), 830 ("f_dir/dir_file_1", Some("foo\n")), 831 ("f_dir/dir_file_2", Some("foo\n")), 832 ("f_dir/dir_file_3", Some("foo\n")), 833 ], 834 ); 835 836 // create a conflicted commit to check the completions of `jj restore` 837 create_commit( 838 &work_dir, 839 "conflicted", 840 &["second"], 841 &[ 842 ("f_modified", Some("modified_again\n")), 843 ("f_added_2", Some("added_2\n")), 844 ("f_dir/dir_file_1", Some("bar\n")), 845 ("f_dir/dir_file_2", Some("bar\n")), 846 ("f_dir/dir_file_3", Some("bar\n")), 847 ], 848 ); 849 work_dir.run_jj(["rebase", "-r=@", "-d=first"]).success(); 850 851 // two commits that are similar but not identical, for `jj interdiff` 852 create_commit( 853 &work_dir, 854 "interdiff_from", 855 &[], 856 &[ 857 ("f_interdiff_same", Some("same in both commits\n")), 858 (("f_interdiff_only_from"), Some("only from\n")), 859 ], 860 ); 861 create_commit( 862 &work_dir, 863 "interdiff_to", 864 &[], 865 &[ 866 ("f_interdiff_same", Some("same in both commits\n")), 867 (("f_interdiff_only_to"), Some("only to\n")), 868 ], 869 ); 870 871 // "dirty worktree" 872 create_commit( 873 &work_dir, 874 "working_copy", 875 &["second"], 876 &[ 877 ("f_modified", Some("modified_again\n")), 878 ("f_added_2", Some("added_2\n")), 879 ], 880 ); 881 882 let output = work_dir.run_jj(["log", "-r", "all()", "--summary"]); 883 insta::assert_snapshot!(output.normalize_backslash(), @r" 884 @ wqnwkozp test.user@example.com 2001-02-03 08:05:20 working_copy cb594eba 885 │ working_copy 886 │ A f_added_2 887 │ M f_modified 888 ○ zsuskuln test.user@example.com 2001-02-03 08:05:11 second 24242473 889 │ second 890 │ A f_added 891 │ D f_deleted 892 │ A f_dir/dir_file_1 893 │ A f_dir/dir_file_2 894 │ A f_dir/dir_file_3 895 │ M f_modified 896 │ R {f_not_yet_renamed => f_renamed} 897 │ × royxmykx test.user@example.com 2001-02-03 08:05:14 conflicted 0ba6786b conflict 898 ├─╯ conflicted 899 │ A f_added_2 900 │ A f_dir/dir_file_1 901 │ A f_dir/dir_file_2 902 │ A f_dir/dir_file_3 903 │ M f_modified 904 ○ rlvkpnrz test.user@example.com 2001-02-03 08:05:09 first 2a2f433c 905 │ first 906 │ A f_deleted 907 │ A f_modified 908 │ A f_not_yet_renamed 909 │ A f_unchanged 910 │ ○ kpqxywon test.user@example.com 2001-02-03 08:05:18 interdiff_to 302c4041 911 ├─╯ interdiff_to 912 │ A f_interdiff_only_to 913 │ A f_interdiff_same 914 │ ○ yostqsxw test.user@example.com 2001-02-03 08:05:16 interdiff_from 083d1cc6 915 ├─╯ interdiff_from 916 │ A f_interdiff_only_from 917 │ A f_interdiff_same 918 ◆ zzzzzzzz root() 00000000 919 [EOF] 920 "); 921 922 let mut test_env = test_env; 923 test_env.add_env_var("COMPLETE", "fish"); 924 let test_env = test_env; 925 let work_dir = test_env.work_dir("repo"); 926 927 let output = work_dir.run_jj(["--", "jj", "file", "show", "f_"]); 928 insta::assert_snapshot!(output.normalize_backslash(), @r" 929 f_added 930 f_added_2 931 f_dir/ 932 f_modified 933 f_renamed 934 f_unchanged 935 [EOF] 936 "); 937 938 let output = work_dir.run_jj(["--", "jj", "file", "annotate", "-r@-", "f_"]); 939 insta::assert_snapshot!(output.normalize_backslash(), @r" 940 f_added 941 f_dir/ 942 f_modified 943 f_renamed 944 f_unchanged 945 [EOF] 946 "); 947 let output = work_dir.run_jj(["--", "jj", "diff", "-r", "@-", "f_"]); 948 insta::assert_snapshot!(output.normalize_backslash(), @r" 949 f_added Added 950 f_deleted Deleted 951 f_dir/ 952 f_modified Modified 953 f_not_yet_renamed Renamed 954 f_renamed Renamed 955 [EOF] 956 "); 957 958 let output = work_dir.run_jj([ 959 "--", 960 "jj", 961 "diff", 962 "-r", 963 "@-", 964 &format!("f_dir{}", std::path::MAIN_SEPARATOR), 965 ]); 966 insta::assert_snapshot!(output.normalize_backslash(), @r" 967 f_dir/dir_file_1 Added 968 f_dir/dir_file_2 Added 969 f_dir/dir_file_3 Added 970 [EOF] 971 "); 972 973 let output = work_dir.run_jj(["--", "jj", "diff", "--from", "root()", "--to", "@-", "f_"]); 974 insta::assert_snapshot!(output.normalize_backslash(), @r" 975 f_added Added 976 f_dir/ 977 f_modified Added 978 f_renamed Added 979 f_unchanged Added 980 [EOF] 981 "); 982 983 // interdiff has a different behavior with --from and --to flags 984 let output = work_dir.run_jj([ 985 "--", 986 "jj", 987 "interdiff", 988 "--to=interdiff_to", 989 "--from=interdiff_from", 990 "f_", 991 ]); 992 insta::assert_snapshot!(output.normalize_backslash(), @r" 993 f_interdiff_only_from Added 994 f_interdiff_same Added 995 f_interdiff_only_to Added 996 f_interdiff_same Added 997 [EOF] 998 "); 999 1000 // squash has a different behavior with --from and --to flags 1001 let output = work_dir.run_jj(["--", "jj", "squash", "-f=first", "f_"]); 1002 insta::assert_snapshot!(output.normalize_backslash(), @r" 1003 f_deleted Added 1004 f_modified Added 1005 f_not_yet_renamed Added 1006 f_unchanged Added 1007 [EOF] 1008 "); 1009 1010 let output = work_dir.run_jj(["--", "jj", "resolve", "-r=conflicted", "f_"]); 1011 insta::assert_snapshot!(output.normalize_backslash(), @r" 1012 f_dir/ 1013 f_modified 1014 [EOF] 1015 "); 1016 1017 let output = work_dir.run_jj(["--", "jj", "log", "f_"]); 1018 insta::assert_snapshot!(output.normalize_backslash(), @r" 1019 f_added 1020 f_added_2 1021 f_dir/ 1022 f_modified 1023 f_renamed 1024 f_unchanged 1025 [EOF] 1026 "); 1027 let output = work_dir.run_jj([ 1028 "--", 1029 "jj", 1030 "log", 1031 "-r=first", 1032 "--revisions", 1033 "conflicted", 1034 "f_", 1035 ]); 1036 insta::assert_snapshot!(output.normalize_backslash(), @r" 1037 f_added_2 1038 f_deleted 1039 f_dir/ 1040 f_modified 1041 f_not_yet_renamed 1042 f_unchanged 1043 [EOF] 1044 "); 1045 1046 let outside_repo = test_env.env_root(); 1047 let output = test_env.run_jj_in(outside_repo, ["--", "jj", "log", "f_"]); 1048 insta::assert_snapshot!(output, @""); 1049}