just playing with tangled
at ig/vimdiffwarn 476 lines 16 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 test_case::test_case; 16 17use crate::common::CommandOutput; 18use crate::common::TestEnvironment; 19use crate::common::TestWorkDir; 20 21#[must_use] 22fn get_log_output_with_bookmarks(work_dir: &TestWorkDir) -> CommandOutput { 23 // Don't include commit IDs since they will be different depending on 24 // whether the test runs with `jj commit` or `jj describe` + `jj new`. 25 let template = r#""bookmarks{" ++ local_bookmarks ++ "} desc: " ++ description"#; 26 work_dir.run_jj(["log", "-T", template]) 27} 28 29fn set_advance_bookmarks(test_env: &TestEnvironment, enabled: bool) { 30 if enabled { 31 test_env.add_config( 32 r#"[experimental-advance-branches] 33 enabled-branches = ["glob:*"] 34 "#, 35 ); 36 } else { 37 test_env.add_config( 38 r#"[experimental-advance-branches] 39 enabled-branches = [] 40 "#, 41 ); 42 } 43} 44 45// Runs a command in the specified test workspace that describes the current 46// commit with `commit_message` and creates a new commit on top of it. 47type CommitFn = fn(work_dir: &TestWorkDir, commit_message: &str); 48 49// Implements CommitFn using the `jj commit` command. 50fn commit_cmd(work_dir: &TestWorkDir, commit_message: &str) { 51 work_dir.run_jj(["commit", "-m", commit_message]).success(); 52} 53 54// Implements CommitFn using the `jj describe` and `jj new`. 55fn describe_new_cmd(work_dir: &TestWorkDir, commit_message: &str) { 56 work_dir 57 .run_jj(["describe", "-m", commit_message]) 58 .success(); 59 work_dir.run_jj(["new"]).success(); 60} 61 62// Check that enabling and disabling advance-bookmarks works as expected. 63#[test_case(commit_cmd ; "commit")] 64#[test_case(describe_new_cmd; "new")] 65fn test_advance_bookmarks_enabled(make_commit: CommitFn) { 66 let test_env = TestEnvironment::default(); 67 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 68 let work_dir = test_env.work_dir("repo"); 69 70 // First, test with advance-bookmarks enabled. Start by creating a bookmark on 71 // the root commit. 72 set_advance_bookmarks(&test_env, true); 73 work_dir 74 .run_jj(["bookmark", "create", "-r", "@-", "test_bookmark"]) 75 .success(); 76 77 // Check the initial state of the repo. 78 insta::allow_duplicates! { 79 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 80 @ bookmarks{} desc: 81 ◆ bookmarks{test_bookmark} desc: 82 [EOF] 83 "); 84 } 85 86 // Run jj commit, which will advance the bookmark pointing to @-. 87 make_commit(&work_dir, "first"); 88 insta::allow_duplicates! { 89 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 90 @ bookmarks{} desc: 91 ○ bookmarks{test_bookmark} desc: first 92 ◆ bookmarks{} desc: 93 [EOF] 94 "); 95 } 96 97 // Now disable advance bookmarks and commit again. The bookmark shouldn't move. 98 set_advance_bookmarks(&test_env, false); 99 make_commit(&work_dir, "second"); 100 insta::allow_duplicates! { 101 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 102 @ bookmarks{} desc: 103 ○ bookmarks{} desc: second 104 ○ bookmarks{test_bookmark} desc: first 105 ◆ bookmarks{} desc: 106 [EOF] 107 "); 108 } 109} 110 111// Check that only a bookmark pointing to @- advances. Branches pointing to @ 112// are not advanced. 113#[test_case(commit_cmd ; "commit")] 114#[test_case(describe_new_cmd; "new")] 115fn test_advance_bookmarks_at_minus(make_commit: CommitFn) { 116 let test_env = TestEnvironment::default(); 117 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 118 let work_dir = test_env.work_dir("repo"); 119 120 set_advance_bookmarks(&test_env, true); 121 work_dir 122 .run_jj(["bookmark", "create", "test_bookmark", "-r", "@"]) 123 .success(); 124 125 insta::allow_duplicates! { 126 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 127 @ bookmarks{test_bookmark} desc: 128 ◆ bookmarks{} desc: 129 [EOF] 130 "); 131 } 132 133 make_commit(&work_dir, "first"); 134 insta::allow_duplicates! { 135 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 136 @ bookmarks{} desc: 137 ○ bookmarks{test_bookmark} desc: first 138 ◆ bookmarks{} desc: 139 [EOF] 140 "); 141 } 142 143 // Create a second bookmark pointing to @. On the next commit, only the first 144 // bookmark, which points to @-, will advance. 145 work_dir 146 .run_jj(["bookmark", "create", "test_bookmark2", "-r", "@"]) 147 .success(); 148 make_commit(&work_dir, "second"); 149 insta::allow_duplicates! { 150 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 151 @ bookmarks{} desc: 152 ○ bookmarks{test_bookmark test_bookmark2} desc: second 153 ○ bookmarks{} desc: first 154 ◆ bookmarks{} desc: 155 [EOF] 156 "); 157 } 158} 159 160// Test that per-bookmark overrides invert the behavior of 161// experimental-advance-bookmarks.enabled. 162#[test_case(commit_cmd ; "commit")] 163#[test_case(describe_new_cmd; "new")] 164fn test_advance_bookmarks_overrides(make_commit: CommitFn) { 165 let test_env = TestEnvironment::default(); 166 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 167 let work_dir = test_env.work_dir("repo"); 168 169 // advance-bookmarks is disabled by default. 170 work_dir 171 .run_jj(["bookmark", "create", "-r", "@-", "test_bookmark"]) 172 .success(); 173 174 // Check the initial state of the repo. 175 insta::allow_duplicates! { 176 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 177 @ bookmarks{} desc: 178 ◆ bookmarks{test_bookmark} desc: 179 [EOF] 180 "); 181 } 182 183 // Commit will not advance the bookmark since advance-bookmarks is disabled. 184 make_commit(&work_dir, "first"); 185 insta::allow_duplicates! { 186 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 187 @ bookmarks{} desc: 188 ○ bookmarks{} desc: first 189 ◆ bookmarks{test_bookmark} desc: 190 [EOF] 191 "); 192 } 193 194 // Now enable advance bookmarks for "test_bookmark", move the bookmark, and 195 // commit again. 196 test_env.add_config( 197 r#"[experimental-advance-bookmarks] 198 enabled-bookmarks = ["test_bookmark"] 199 "#, 200 ); 201 work_dir 202 .run_jj(["bookmark", "set", "test_bookmark", "-r", "@-"]) 203 .success(); 204 insta::allow_duplicates! { 205 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 206 @ bookmarks{} desc: 207 ○ bookmarks{test_bookmark} desc: first 208 ◆ bookmarks{} desc: 209 [EOF] 210 "); 211 } 212 make_commit(&work_dir, "second"); 213 insta::allow_duplicates! { 214 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 215 @ bookmarks{} desc: 216 ○ bookmarks{} desc: second 217 ○ bookmarks{test_bookmark} desc: first 218 ◆ bookmarks{} desc: 219 [EOF] 220 "); 221 } 222 223 // Now disable advance bookmarks for "test_bookmark" and "second_bookmark", 224 // which we will use later. Disabling always takes precedence over enabling. 225 test_env.add_config( 226 r#"[experimental-advance-bookmarks] 227 enabled-bookmarks = ["test_bookmark", "second_bookmark"] 228 disabled-bookmarks = ["test_bookmark"] 229 "#, 230 ); 231 make_commit(&work_dir, "third"); 232 insta::allow_duplicates! { 233 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 234 @ bookmarks{} desc: 235 ○ bookmarks{} desc: third 236 ○ bookmarks{} desc: second 237 ○ bookmarks{test_bookmark} desc: first 238 ◆ bookmarks{} desc: 239 [EOF] 240 "); 241 } 242 243 // If we create a new bookmark at @- and move test_bookmark there as well. When 244 // we commit, only "second_bookmark" will advance since "test_bookmark" is 245 // disabled. 246 work_dir 247 .run_jj(["bookmark", "create", "second_bookmark", "-r", "@-"]) 248 .success(); 249 work_dir 250 .run_jj(["bookmark", "set", "test_bookmark", "-r", "@-"]) 251 .success(); 252 insta::allow_duplicates! { 253 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 254 @ bookmarks{} desc: 255 ○ bookmarks{second_bookmark test_bookmark} desc: third 256 ○ bookmarks{} desc: second 257 ○ bookmarks{} desc: first 258 ◆ bookmarks{} desc: 259 [EOF] 260 "); 261 } 262 make_commit(&work_dir, "fourth"); 263 insta::allow_duplicates! { 264 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 265 @ bookmarks{} desc: 266 ○ bookmarks{} desc: fourth 267 ○ bookmarks{second_bookmark test_bookmark} desc: third 268 ○ bookmarks{} desc: second 269 ○ bookmarks{} desc: first 270 ◆ bookmarks{} desc: 271 [EOF] 272 "); 273 } 274} 275 276// If multiple eligible bookmarks point to @-, all of them will be advanced. 277#[test_case(commit_cmd ; "commit")] 278#[test_case(describe_new_cmd; "new")] 279fn test_advance_bookmarks_multiple_bookmarks(make_commit: CommitFn) { 280 let test_env = TestEnvironment::default(); 281 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 282 let work_dir = test_env.work_dir("repo"); 283 284 set_advance_bookmarks(&test_env, true); 285 work_dir 286 .run_jj(["bookmark", "create", "-r", "@-", "first_bookmark"]) 287 .success(); 288 work_dir 289 .run_jj(["bookmark", "create", "-r", "@-", "second_bookmark"]) 290 .success(); 291 292 insta::allow_duplicates! { 293 // Check the initial state of the repo. 294 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 295 @ bookmarks{} desc: 296 ◆ bookmarks{first_bookmark second_bookmark} desc: 297 [EOF] 298 "); 299 } 300 301 // Both bookmarks are eligible and both will advance. 302 make_commit(&work_dir, "first"); 303 insta::allow_duplicates! { 304 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 305 @ bookmarks{} desc: 306 ○ bookmarks{first_bookmark second_bookmark} desc: first 307 ◆ bookmarks{} desc: 308 [EOF] 309 "); 310 } 311} 312 313// Call `jj new` on an interior commit and see that the bookmark pointing to its 314// parent's parent is advanced. 315#[test] 316fn test_new_advance_bookmarks_interior() { 317 let test_env = TestEnvironment::default(); 318 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 319 let work_dir = test_env.work_dir("repo"); 320 321 set_advance_bookmarks(&test_env, true); 322 323 // Check the initial state of the repo. 324 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 325 @ bookmarks{} desc: 326 ◆ bookmarks{} desc: 327 [EOF] 328 "); 329 330 // Create a gap in the commits for us to insert our new commit with --before. 331 work_dir.run_jj(["commit", "-m", "first"]).success(); 332 work_dir.run_jj(["commit", "-m", "second"]).success(); 333 work_dir.run_jj(["commit", "-m", "third"]).success(); 334 work_dir 335 .run_jj(["bookmark", "create", "-r", "@---", "test_bookmark"]) 336 .success(); 337 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 338 @ bookmarks{} desc: 339 ○ bookmarks{} desc: third 340 ○ bookmarks{} desc: second 341 ○ bookmarks{test_bookmark} desc: first 342 ◆ bookmarks{} desc: 343 [EOF] 344 "); 345 346 work_dir.run_jj(["new", "-r", "@--"]).success(); 347 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 348 @ bookmarks{} desc: 349 │ ○ bookmarks{} desc: third 350 ├─╯ 351 ○ bookmarks{test_bookmark} desc: second 352 ○ bookmarks{} desc: first 353 ◆ bookmarks{} desc: 354 [EOF] 355 "); 356} 357 358// If the `--before` flag is passed to `jj new`, bookmarks are not advanced. 359#[test] 360fn test_new_advance_bookmarks_before() { 361 let test_env = TestEnvironment::default(); 362 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 363 let work_dir = test_env.work_dir("repo"); 364 365 set_advance_bookmarks(&test_env, true); 366 367 // Check the initial state of the repo. 368 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 369 @ bookmarks{} desc: 370 ◆ bookmarks{} desc: 371 [EOF] 372 "); 373 374 // Create a gap in the commits for us to insert our new commit with --before. 375 work_dir.run_jj(["commit", "-m", "first"]).success(); 376 work_dir.run_jj(["commit", "-m", "second"]).success(); 377 work_dir.run_jj(["commit", "-m", "third"]).success(); 378 work_dir 379 .run_jj(["bookmark", "create", "-r", "@---", "test_bookmark"]) 380 .success(); 381 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 382 @ bookmarks{} desc: 383 ○ bookmarks{} desc: third 384 ○ bookmarks{} desc: second 385 ○ bookmarks{test_bookmark} desc: first 386 ◆ bookmarks{} desc: 387 [EOF] 388 "); 389 390 work_dir.run_jj(["new", "--before", "@-"]).success(); 391 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 392 ○ bookmarks{} desc: third 393 @ bookmarks{} desc: 394 ○ bookmarks{} desc: second 395 ○ bookmarks{test_bookmark} desc: first 396 ◆ bookmarks{} desc: 397 [EOF] 398 "); 399} 400 401// If the `--after` flag is passed to `jj new`, bookmarks are not advanced. 402#[test] 403fn test_new_advance_bookmarks_after() { 404 let test_env = TestEnvironment::default(); 405 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 406 let work_dir = test_env.work_dir("repo"); 407 408 set_advance_bookmarks(&test_env, true); 409 work_dir 410 .run_jj(["bookmark", "create", "-r", "@-", "test_bookmark"]) 411 .success(); 412 413 // Check the initial state of the repo. 414 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 415 @ bookmarks{} desc: 416 ◆ bookmarks{test_bookmark} desc: 417 [EOF] 418 "); 419 420 work_dir.run_jj(["describe", "-m", "first"]).success(); 421 work_dir.run_jj(["new", "--after", "@"]).success(); 422 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 423 @ bookmarks{} desc: 424 ○ bookmarks{} desc: first 425 ◆ bookmarks{test_bookmark} desc: 426 [EOF] 427 "); 428} 429 430#[test] 431fn test_new_advance_bookmarks_merge_children() { 432 let test_env = TestEnvironment::default(); 433 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 434 let work_dir = test_env.work_dir("repo"); 435 436 set_advance_bookmarks(&test_env, true); 437 work_dir.run_jj(["desc", "-m", "0"]).success(); 438 work_dir.run_jj(["new", "-m", "1"]).success(); 439 work_dir 440 .run_jj(["new", "description(0)", "-m", "2"]) 441 .success(); 442 work_dir 443 .run_jj([ 444 "bookmark", 445 "create", 446 "test_bookmark", 447 "-r", 448 "description(0)", 449 ]) 450 .success(); 451 452 // Check the initial state of the repo. 453 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 454 @ bookmarks{} desc: 2 455 │ ○ bookmarks{} desc: 1 456 ├─╯ 457 ○ bookmarks{test_bookmark} desc: 0 458 ◆ bookmarks{} desc: 459 [EOF] 460 "); 461 462 // The bookmark won't advance because `jj new` had multiple targets. 463 work_dir 464 .run_jj(["new", "description(1)", "description(2)"]) 465 .success(); 466 insta::assert_snapshot!(get_log_output_with_bookmarks(&work_dir), @r" 467 @ bookmarks{} desc: 468 ├─╮ 469 │ ○ bookmarks{} desc: 2 470 ○ │ bookmarks{} desc: 1 471 ├─╯ 472 ○ bookmarks{test_bookmark} desc: 0 473 ◆ bookmarks{} desc: 474 [EOF] 475 "); 476}