just playing with tangled
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}