just playing with tangled
at ig/vimdiffwarn 554 lines 23 kB view raw
1// Copyright 2022 The Jujutsu Authors 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// https://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14use std::path::Path; 15 16use testutils::git; 17 18use crate::common::CommandOutput; 19use crate::common::TestEnvironment; 20 21#[test] 22fn test_undo_rewrite_with_child() { 23 // Test that if we undo an operation that rewrote some commit, any descendants 24 // after that will be rebased on top of the un-rewritten commit. 25 let test_env = TestEnvironment::default(); 26 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 27 let repo_path = test_env.env_root().join("repo"); 28 29 test_env 30 .run_jj_in(&repo_path, ["describe", "-m", "initial"]) 31 .success(); 32 test_env 33 .run_jj_in(&repo_path, ["describe", "-m", "modified"]) 34 .success(); 35 let output = test_env.run_jj_in(&repo_path, ["op", "log"]).success(); 36 let op_id_hex = output.stdout.raw()[3..15].to_string(); 37 test_env 38 .run_jj_in(&repo_path, ["new", "-m", "child"]) 39 .success(); 40 let output = test_env.run_jj_in(&repo_path, ["log", "-T", "description"]); 41 insta::assert_snapshot!(output, @r" 42 @ child 43 ○ modified 44 45 [EOF] 46 "); 47 test_env 48 .run_jj_in(&repo_path, ["undo", &op_id_hex]) 49 .success(); 50 51 // Since we undid the description-change, the child commit should now be on top 52 // of the initial commit 53 let output = test_env.run_jj_in(&repo_path, ["log", "-T", "description"]); 54 insta::assert_snapshot!(output, @r" 55 @ child 56 ○ initial 57 58 [EOF] 59 "); 60} 61 62#[test] 63fn test_git_push_undo() { 64 let test_env = TestEnvironment::default(); 65 test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); 66 let git_repo_path = test_env.env_root().join("git-repo"); 67 git::init_bare(git_repo_path); 68 test_env 69 .run_jj_in(".", ["git", "clone", "git-repo", "repo"]) 70 .success(); 71 let repo_path = test_env.env_root().join("repo"); 72 73 test_env.advance_test_rng_seed_to_multiple_of(100_000); 74 test_env 75 .run_jj_in(&repo_path, ["bookmark", "create", "-r@", "main"]) 76 .success(); 77 test_env 78 .run_jj_in(&repo_path, ["describe", "-m", "AA"]) 79 .success(); 80 test_env 81 .run_jj_in(&repo_path, ["git", "push", "--allow-new"]) 82 .success(); 83 test_env.advance_test_rng_seed_to_multiple_of(100_000); 84 test_env 85 .run_jj_in(&repo_path, ["describe", "-m", "BB"]) 86 .success(); 87 // Refs at this point look as follows (-- means no ref) 88 // | jj refs | jj's | git 89 // | | git | repo 90 // | |tracking| 91 // ------------------------------------------ 92 // local `main` | BB | -- | -- 93 // remote-tracking | AA | AA | AA 94 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 95 main: qpvuntsm 75e78001 (empty) BB 96 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 2080bdb8 (empty) AA 97 [EOF] 98 "); 99 let pre_push_opid = test_env.work_dir(&repo_path).current_operation_id(); 100 test_env.run_jj_in(&repo_path, ["git", "push"]).success(); 101 // | jj refs | jj's | git 102 // | | git | repo 103 // | |tracking| 104 // ------------------------------------------ 105 // local `main` | BB | -- | -- 106 // remote-tracking | BB | BB | BB 107 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 108 main: qpvuntsm 75e78001 (empty) BB 109 @origin: qpvuntsm 75e78001 (empty) BB 110 [EOF] 111 "); 112 113 // Undo the push 114 test_env 115 .run_jj_in(&repo_path, ["op", "restore", &pre_push_opid]) 116 .success(); 117 // | jj refs | jj's | git 118 // | | git | repo 119 // | |tracking| 120 // ------------------------------------------ 121 // local `main` | BB | -- | -- 122 // remote-tracking | AA | AA | BB 123 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 124 main: qpvuntsm 75e78001 (empty) BB 125 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 2080bdb8 (empty) AA 126 [EOF] 127 "); 128 test_env.advance_test_rng_seed_to_multiple_of(100_000); 129 test_env 130 .run_jj_in(&repo_path, ["describe", "-m", "CC"]) 131 .success(); 132 test_env.run_jj_in(&repo_path, ["git", "fetch"]).success(); 133 // TODO: The user would probably not expect a conflict here. It currently is 134 // because the undo made us forget that the remote was at v2, so the fetch 135 // made us think it updated from v1 to v2 (instead of the no-op it could 136 // have been). 137 // 138 // One option to solve this would be to have undo not restore remote-tracking 139 // bookmarks, but that also has undersired consequences: the second fetch in 140 // `jj git fetch && jj undo && jj git fetch` would become a no-op. 141 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 142 main (conflicted): 143 - qpvuntsm hidden 2080bdb8 (empty) AA 144 + qpvuntsm?? 20b2cc4b (empty) CC 145 + qpvuntsm?? 75e78001 (empty) BB 146 @origin (behind by 1 commits): qpvuntsm?? 75e78001 (empty) BB 147 [EOF] 148 "); 149} 150 151/// This test is identical to the previous one, except for one additional 152/// import. It demonstrates that this changes the outcome. 153#[test] 154fn test_git_push_undo_with_import() { 155 let test_env = TestEnvironment::default(); 156 test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); 157 let git_repo_path = test_env.env_root().join("git-repo"); 158 git::init_bare(git_repo_path); 159 test_env 160 .run_jj_in(".", ["git", "clone", "git-repo", "repo"]) 161 .success(); 162 let repo_path = test_env.env_root().join("repo"); 163 164 test_env.advance_test_rng_seed_to_multiple_of(100_000); 165 test_env 166 .run_jj_in(&repo_path, ["bookmark", "create", "-r@", "main"]) 167 .success(); 168 test_env 169 .run_jj_in(&repo_path, ["describe", "-m", "AA"]) 170 .success(); 171 test_env 172 .run_jj_in(&repo_path, ["git", "push", "--allow-new"]) 173 .success(); 174 test_env.advance_test_rng_seed_to_multiple_of(100_000); 175 test_env 176 .run_jj_in(&repo_path, ["describe", "-m", "BB"]) 177 .success(); 178 // Refs at this point look as follows (-- means no ref) 179 // | jj refs | jj's | git 180 // | | git | repo 181 // | |tracking| 182 // ------------------------------------------ 183 // local `main` | BB | -- | -- 184 // remote-tracking | AA | AA | AA 185 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 186 main: qpvuntsm 75e78001 (empty) BB 187 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 2080bdb8 (empty) AA 188 [EOF] 189 "); 190 let pre_push_opid = test_env.work_dir(&repo_path).current_operation_id(); 191 test_env.run_jj_in(&repo_path, ["git", "push"]).success(); 192 // | jj refs | jj's | git 193 // | | git | repo 194 // | |tracking| 195 // ------------------------------------------ 196 // local `main` | BB | -- | -- 197 // remote-tracking | BB | BB | BB 198 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 199 main: qpvuntsm 75e78001 (empty) BB 200 @origin: qpvuntsm 75e78001 (empty) BB 201 [EOF] 202 "); 203 204 // Undo the push 205 test_env 206 .run_jj_in(&repo_path, ["op", "restore", &pre_push_opid]) 207 .success(); 208 // | jj refs | jj's | git 209 // | | git | repo 210 // | |tracking| 211 // ------------------------------------------ 212 // local `main` | BB | -- | -- 213 // remote-tracking | AA | AA | BB 214 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 215 main: qpvuntsm 75e78001 (empty) BB 216 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 2080bdb8 (empty) AA 217 [EOF] 218 "); 219 220 // PROBLEM: inserting this import changes the outcome compared to previous test 221 // TODO: decide if this is the better behavior, and whether import of 222 // remote-tracking bookmarks should happen on every operation. 223 test_env.run_jj_in(&repo_path, ["git", "import"]).success(); 224 // | jj refs | jj's | git 225 // | | git | repo 226 // | |tracking| 227 // ------------------------------------------ 228 // local `main` | BB | -- | -- 229 // remote-tracking | BB | BB | BB 230 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 231 main: qpvuntsm 75e78001 (empty) BB 232 @origin: qpvuntsm 75e78001 (empty) BB 233 [EOF] 234 "); 235 test_env.advance_test_rng_seed_to_multiple_of(100_000); 236 test_env 237 .run_jj_in(&repo_path, ["describe", "-m", "CC"]) 238 .success(); 239 test_env.run_jj_in(&repo_path, ["git", "fetch"]).success(); 240 // There is not a conflict. This seems like a good outcome; undoing `git push` 241 // was essentially a no-op. 242 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 243 main: qpvuntsm 20b2cc4b (empty) CC 244 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 75e78001 (empty) BB 245 [EOF] 246 "); 247} 248 249// This test is currently *identical* to `test_git_push_undo` except the repo 250// it's operating it is colocated. 251#[test] 252fn test_git_push_undo_colocated() { 253 let test_env = TestEnvironment::default(); 254 test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); 255 let git_repo_path = test_env.env_root().join("git-repo"); 256 git::init_bare(git_repo_path.clone()); 257 let repo_path = test_env.env_root().join("clone"); 258 git::clone(&repo_path, git_repo_path.to_str().unwrap(), None); 259 260 test_env 261 .run_jj_in(&repo_path, ["git", "init", "--git-repo=."]) 262 .success(); 263 264 test_env.advance_test_rng_seed_to_multiple_of(100_000); 265 test_env 266 .run_jj_in(&repo_path, ["bookmark", "create", "-r@", "main"]) 267 .success(); 268 test_env 269 .run_jj_in(&repo_path, ["describe", "-m", "AA"]) 270 .success(); 271 test_env 272 .run_jj_in(&repo_path, ["git", "push", "--allow-new"]) 273 .success(); 274 test_env.advance_test_rng_seed_to_multiple_of(100_000); 275 test_env 276 .run_jj_in(&repo_path, ["describe", "-m", "BB"]) 277 .success(); 278 // Refs at this point look as follows (-- means no ref) 279 // | jj refs | jj's | git 280 // | | git | repo 281 // | |tracking| 282 // ------------------------------------------ 283 // local `main` | BB | BB | BB 284 // remote-tracking | AA | AA | AA 285 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 286 main: qpvuntsm 75e78001 (empty) BB 287 @git: qpvuntsm 75e78001 (empty) BB 288 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 2080bdb8 (empty) AA 289 [EOF] 290 "); 291 let pre_push_opid = test_env.work_dir(&repo_path).current_operation_id(); 292 test_env.run_jj_in(&repo_path, ["git", "push"]).success(); 293 // | jj refs | jj's | git 294 // | | git | repo 295 // | |tracking| 296 // ------------------------------------------ 297 // local `main` | BB | BB | BB 298 // remote-tracking | BB | BB | BB 299 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 300 main: qpvuntsm 75e78001 (empty) BB 301 @git: qpvuntsm 75e78001 (empty) BB 302 @origin: qpvuntsm 75e78001 (empty) BB 303 [EOF] 304 "); 305 306 // Undo the push 307 test_env 308 .run_jj_in(&repo_path, ["op", "restore", &pre_push_opid]) 309 .success(); 310 // === Before auto-export ==== 311 // | jj refs | jj's | git 312 // | | git | repo 313 // | |tracking| 314 // ------------------------------------------ 315 // local `main` | BB | BB | BB 316 // remote-tracking | AA | BB | BB 317 // === After automatic `jj git export` ==== 318 // | jj refs | jj's | git 319 // | | git | repo 320 // | |tracking| 321 // ------------------------------------------ 322 // local `main` | BB | BB | BB 323 // remote-tracking | AA | AA | AA 324 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 325 main: qpvuntsm 75e78001 (empty) BB 326 @git: qpvuntsm 75e78001 (empty) BB 327 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 2080bdb8 (empty) AA 328 [EOF] 329 "); 330 test_env.advance_test_rng_seed_to_multiple_of(100_000); 331 test_env 332 .run_jj_in(&repo_path, ["describe", "-m", "CC"]) 333 .success(); 334 test_env.run_jj_in(&repo_path, ["git", "fetch"]).success(); 335 // We have the same conflict as `test_git_push_undo`. TODO: why did we get the 336 // same result in a seemingly different way? 337 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 338 main (conflicted): 339 - qpvuntsm hidden 2080bdb8 (empty) AA 340 + qpvuntsm?? 20b2cc4b (empty) CC 341 + qpvuntsm?? 75e78001 (empty) BB 342 @git (behind by 1 commits): qpvuntsm?? 20b2cc4b (empty) CC 343 @origin (behind by 1 commits): qpvuntsm?? 75e78001 (empty) BB 344 [EOF] 345 "); 346} 347 348// This test is currently *identical* to `test_git_push_undo` except 349// both the git_refs and the remote-tracking bookmarks are preserved by undo. 350// TODO: Investigate the different outcome 351#[test] 352fn test_git_push_undo_repo_only() { 353 let test_env = TestEnvironment::default(); 354 test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); 355 let git_repo_path = test_env.env_root().join("git-repo"); 356 git::init_bare(git_repo_path); 357 test_env 358 .run_jj_in(".", ["git", "clone", "git-repo", "repo"]) 359 .success(); 360 let repo_path = test_env.env_root().join("repo"); 361 362 test_env.advance_test_rng_seed_to_multiple_of(100_000); 363 test_env 364 .run_jj_in(&repo_path, ["bookmark", "create", "-r@", "main"]) 365 .success(); 366 test_env 367 .run_jj_in(&repo_path, ["describe", "-m", "AA"]) 368 .success(); 369 test_env 370 .run_jj_in(&repo_path, ["git", "push", "--allow-new"]) 371 .success(); 372 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 373 main: qpvuntsm 2080bdb8 (empty) AA 374 @origin: qpvuntsm 2080bdb8 (empty) AA 375 [EOF] 376 "); 377 test_env.advance_test_rng_seed_to_multiple_of(100_000); 378 test_env 379 .run_jj_in(&repo_path, ["describe", "-m", "BB"]) 380 .success(); 381 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 382 main: qpvuntsm 75e78001 (empty) BB 383 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 2080bdb8 (empty) AA 384 [EOF] 385 "); 386 let pre_push_opid = test_env.work_dir(&repo_path).current_operation_id(); 387 test_env.run_jj_in(&repo_path, ["git", "push"]).success(); 388 389 // Undo the push, but keep both the git_refs and the remote-tracking bookmarks 390 test_env 391 .run_jj_in(&repo_path, ["op", "restore", "--what=repo", &pre_push_opid]) 392 .success(); 393 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 394 main: qpvuntsm 75e78001 (empty) BB 395 @origin: qpvuntsm 75e78001 (empty) BB 396 [EOF] 397 "); 398 test_env.advance_test_rng_seed_to_multiple_of(100_000); 399 test_env 400 .run_jj_in(&repo_path, ["describe", "-m", "CC"]) 401 .success(); 402 test_env.run_jj_in(&repo_path, ["git", "fetch"]).success(); 403 // This currently gives an identical result to `test_git_push_undo_import`. 404 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 405 main: qpvuntsm 20b2cc4b (empty) CC 406 @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 75e78001 (empty) BB 407 [EOF] 408 "); 409} 410 411#[test] 412fn test_bookmark_track_untrack_undo() { 413 let test_env = TestEnvironment::default(); 414 test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); 415 let git_repo_path = test_env.env_root().join("git-repo"); 416 git::init_bare(git_repo_path); 417 test_env 418 .run_jj_in(".", ["git", "clone", "git-repo", "repo"]) 419 .success(); 420 let repo_path = test_env.env_root().join("repo"); 421 422 test_env 423 .run_jj_in(&repo_path, ["describe", "-mcommit"]) 424 .success(); 425 test_env 426 .run_jj_in( 427 &repo_path, 428 ["bookmark", "create", "-r@", "feature1", "feature2"], 429 ) 430 .success(); 431 test_env 432 .run_jj_in(&repo_path, ["git", "push", "--allow-new"]) 433 .success(); 434 test_env 435 .run_jj_in(&repo_path, ["bookmark", "delete", "feature2"]) 436 .success(); 437 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 438 feature1: qpvuntsm 8da1cfc8 (empty) commit 439 @origin: qpvuntsm 8da1cfc8 (empty) commit 440 feature2 (deleted) 441 @origin: qpvuntsm 8da1cfc8 (empty) commit 442 [EOF] 443 "); 444 445 // Track/untrack can be undone so long as states can be trivially merged. 446 test_env 447 .run_jj_in( 448 &repo_path, 449 ["bookmark", "untrack", "feature1@origin", "feature2@origin"], 450 ) 451 .success(); 452 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 453 feature1: qpvuntsm 8da1cfc8 (empty) commit 454 feature1@origin: qpvuntsm 8da1cfc8 (empty) commit 455 feature2@origin: qpvuntsm 8da1cfc8 (empty) commit 456 [EOF] 457 "); 458 459 test_env.run_jj_in(&repo_path, ["undo"]).success(); 460 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 461 feature1: qpvuntsm 8da1cfc8 (empty) commit 462 @origin: qpvuntsm 8da1cfc8 (empty) commit 463 feature2 (deleted) 464 @origin: qpvuntsm 8da1cfc8 (empty) commit 465 [EOF] 466 "); 467 468 test_env.run_jj_in(&repo_path, ["undo"]).success(); 469 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 470 feature1: qpvuntsm 8da1cfc8 (empty) commit 471 feature1@origin: qpvuntsm 8da1cfc8 (empty) commit 472 feature2@origin: qpvuntsm 8da1cfc8 (empty) commit 473 [EOF] 474 "); 475 476 test_env 477 .run_jj_in(&repo_path, ["bookmark", "track", "feature1@origin"]) 478 .success(); 479 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 480 feature1: qpvuntsm 8da1cfc8 (empty) commit 481 @origin: qpvuntsm 8da1cfc8 (empty) commit 482 feature2@origin: qpvuntsm 8da1cfc8 (empty) commit 483 [EOF] 484 "); 485 486 test_env.run_jj_in(&repo_path, ["undo"]).success(); 487 insta::assert_snapshot!(get_bookmark_output(&test_env, &repo_path), @r" 488 feature1: qpvuntsm 8da1cfc8 (empty) commit 489 feature1@origin: qpvuntsm 8da1cfc8 (empty) commit 490 feature2@origin: qpvuntsm 8da1cfc8 (empty) commit 491 [EOF] 492 "); 493} 494 495#[test] 496fn test_shows_a_warning_when_undoing_an_undo_operation_as_bare_jj_undo() { 497 let test_env = TestEnvironment::default(); 498 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 499 let repo_path = test_env.env_root().join("repo"); 500 501 // Double-undo creation of child 502 test_env.run_jj_in(&repo_path, ["new"]).success(); 503 test_env.run_jj_in(&repo_path, ["undo"]).success(); 504 let output = test_env.run_jj_in(&repo_path, ["undo"]); 505 insta::assert_snapshot!(output, @r" 506 ------- stderr ------- 507 Undid operation: 2d5b73a97567 (2001-02-03 08:05:09) undo operation 289cb69a8458456474a77cc432e8009b99f039cdcaf19ba4526753e97d70fee3fd0f410ff2b7c1d10cf0c2501702e7a85d58f9d813cdca567c377431ec4d2b97 508 Working copy (@) now at: rlvkpnrz 65b6b74e (empty) (no description set) 509 Parent commit (@-) : qpvuntsm 230dd059 (empty) (no description set) 510 Hint: This action reverted an 'undo' operation. The repository is now in the same state as it was before the original 'undo'. 511 Hint: If your goal is to undo multiple operations, consider using `jj op log` to see past states, and `jj op restore` to restore one of these states. 512 [EOF] 513 "); 514 515 // Double-undo creation of sibling 516 test_env.run_jj_in(&repo_path, ["new", "@-"]).success(); 517 test_env.run_jj_in(&repo_path, ["undo"]).success(); 518 let output = test_env.run_jj_in(&repo_path, ["undo"]); 519 insta::assert_snapshot!(output, @r" 520 ------- stderr ------- 521 Undid operation: b16799358b33 (2001-02-03 08:05:12) undo operation b14487c6d6d98f7f575ea03c48ed92d899c2a0ecbe9458221b6fc11af2bf6d918c9620cae1f8268012b0e25c7dd6f78b19ec628d0504a0830dc562d6625ba9ec 522 Working copy (@) now at: mzvwutvl 167f90e7 (empty) (no description set) 523 Parent commit (@-) : qpvuntsm 230dd059 (empty) (no description set) 524 Hint: This action reverted an 'undo' operation. The repository is now in the same state as it was before the original 'undo'. 525 Hint: If your goal is to undo multiple operations, consider using `jj op log` to see past states, and `jj op restore` to restore one of these states. 526 [EOF] 527 "); 528} 529 530#[test] 531fn test_shows_no_warning_when_undoing_a_specific_undo_change() { 532 let test_env = TestEnvironment::default(); 533 test_env.run_jj_in(".", ["git", "init", "repo"]).success(); 534 let repo_path = test_env.env_root().join("repo"); 535 536 test_env.run_jj_in(&repo_path, ["new"]).success(); 537 test_env.run_jj_in(&repo_path, ["undo"]).success(); 538 let output = test_env.run_jj_in(&repo_path, ["op", "log"]).success(); 539 let op_id_hex = output.stdout.raw()[3..15].to_string(); 540 let output = test_env.run_jj_in(&repo_path, ["undo", &op_id_hex]); 541 insta::assert_snapshot!(output, @r" 542 ------- stderr ------- 543 Undid operation: 2d5b73a97567 (2001-02-03 08:05:09) undo operation 289cb69a8458456474a77cc432e8009b99f039cdcaf19ba4526753e97d70fee3fd0f410ff2b7c1d10cf0c2501702e7a85d58f9d813cdca567c377431ec4d2b97 544 Working copy (@) now at: rlvkpnrz 65b6b74e (empty) (no description set) 545 Parent commit (@-) : qpvuntsm 230dd059 (empty) (no description set) 546 [EOF] 547 "); 548} 549 550#[must_use] 551fn get_bookmark_output(test_env: &TestEnvironment, repo_path: &Path) -> CommandOutput { 552 // --quiet to suppress deleted bookmarks hint 553 test_env.run_jj_in(repo_path, ["bookmark", "list", "--all-remotes", "--quiet"]) 554}