// Copyright 2022 The Jujutsu Authors//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// https://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License. use testutils::git; use crate::common::CommandOutput;use crate::common::TestEnvironment;use crate::common::TestWorkDir; fn create_commit_with_refs( repo: &gix::Repository, message: &str, content: &[u8], ref_names: &[&str],) { let git::CommitResult { tree_id: _, commit_id, } = git::add_commit(repo, "refs/heads/dummy", "file", content, message, &[]); repo.find_reference("dummy").unwrap().delete().unwrap(); for name in ref_names { repo.reference( *name, commit_id, gix::refs::transaction::PreviousValue::Any, "log message", ) .unwrap(); }} #[test]fn test_bookmark_multiple_names() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo", "bar"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 2 bookmarks pointing to qpvuntsm 230dd059 bar foo | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ bar foo 230dd059e1b0 ◆ 000000000000 [EOF] "); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["bookmark", "set", "foo", "bar", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 2 bookmarks to zsuskuln 8bb159bc bar foo | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ bar foo 8bb159bc30a9 ○ 230dd059e1b0 ◆ 000000000000 [EOF] "); let output = work_dir.run_jj(["bookmark", "delete", "foo", "bar", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Deleted 2 bookmarks. [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 8bb159bc30a9 ○ 230dd059e1b0 ◆ 000000000000 [EOF] "); // Hint should be omitted if -r is specified let output = work_dir.run_jj(["bookmark", "create", "-r@-", "foo", "bar"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 2 bookmarks pointing to qpvuntsm 230dd059 bar foo | (empty) (no description set) [EOF] "); // Create and move with explicit -r let output = work_dir.run_jj(["bookmark", "set", "-r@", "bar", "baz"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to zsuskuln 8bb159bc bar baz | (empty) (no description set) Moved 1 bookmarks to zsuskuln 8bb159bc bar baz | (empty) (no description set) [EOF] "); // Noop changes should not be included in the stats let output = work_dir.run_jj(["bookmark", "set", "-r@", "foo", "bar", "baz"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to zsuskuln 8bb159bc bar baz foo | (empty) (no description set) [EOF] ");} #[test]fn test_bookmark_at_root() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["bookmark", "create", "fred", "-r=root()"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to zzzzzzzz 00000000 fred | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["git", "export"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. Warning: Failed to export some bookmarks: fred@git: Ref cannot point to the root commit in Git [EOF] ");} #[test]fn test_bookmark_bad_name() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["bookmark", "create", "-r@", ""]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '' for '<NAMES>...': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:1 | 1 | | ^--- | = expected <identifier>, <string_literal>, or <raw_string_literal> Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); let output = work_dir.run_jj(["bookmark", "set", "''"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '''' for '<NAMES>...': Failed to parse bookmark name: Expected non-empty string For more information, try '--help'. Caused by: --> 1:1 | 1 | '' | ^^ | = Expected non-empty string Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); let output = work_dir.run_jj(["bookmark", "rename", "x", ""]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '' for '<NEW>': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:1 | 1 | | ^--- | = expected <identifier>, <string_literal>, or <raw_string_literal> Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); // common errors let output = work_dir.run_jj(["bookmark", "set", "@-", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '@-' for '<NAMES>...': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:1 | 1 | @- | ^--- | = expected <identifier>, <string_literal>, or <raw_string_literal> Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); let stderr = work_dir.run_jj(["bookmark", "set", "-r@-", "foo@bar"]); insta::assert_snapshot!(stderr, @r" ------- stderr ------- error: invalid value 'foo@bar' for '<NAMES>...': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:4 | 1 | foo@bar | ^--- | = expected <EOI> Hint: Looks like remote bookmark. Run `jj bookmark track foo@bar` to track it. [EOF] [exit status: 2] "); // quoted name works let output = work_dir.run_jj(["bookmark", "create", "-r@", "'foo@bar'"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to qpvuntsm 230dd059 foo@bar | (empty) (no description set) [EOF] ");} #[test]fn test_bookmark_move() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); // Set up remote let git_repo_path = test_env.env_root().join("git-repo"); git::init_bare(git_repo_path); work_dir .run_jj(["git", "remote", "add", "origin", "../git-repo"]) .success(); let output = work_dir.run_jj(["bookmark", "move", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: No such bookmark: foo [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "set", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to qpvuntsm 230dd059 foo | (empty) (no description set) [EOF] "); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Bookmark already exists: foo Hint: Use `jj bookmark set` to update it. [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "set", "foo", "--revision", "@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to mzvwutvl 167f90e7 foo | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["bookmark", "set", "-r@-", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Refusing to move bookmark backwards or sideways: foo Hint: Use --allow-backwards to allow it. [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "set", "-r@-", "--allow-backwards", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to qpvuntsm 230dd059 foo | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["bookmark", "move", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to mzvwutvl 167f90e7 foo | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["bookmark", "move", "--to=@-", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Refusing to move bookmark backwards or sideways: foo Hint: Use --allow-backwards to allow it. [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "move", "--to=@-", "--allow-backwards", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to qpvuntsm 230dd059 foo | (empty) (no description set) [EOF] "); // Delete bookmark locally, but is still tracking remote work_dir.run_jj(["describe", "@-", "-mcommit"]).success(); work_dir .run_jj(["git", "push", "--allow-new", "-r@-"]) .success(); work_dir.run_jj(["bookmark", "delete", "foo"]).success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" foo (deleted) @origin: qpvuntsm 1eb845f3 (empty) commit [EOF] "); // Deleted tracking bookmark name should still be allocated let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Tracked remote bookmarks exist for deleted bookmark: foo Hint: Use `jj bookmark set` to recreate the local bookmark. Run `jj bookmark untrack 'glob:foo@*'` to disassociate them. [EOF] [exit status: 1] "); // Restoring local target shouldn't invalidate tracking state let output = work_dir.run_jj(["bookmark", "set", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to mzvwutvl 66d48752 foo* | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" foo: mzvwutvl 66d48752 (empty) (no description set) @origin (behind by 1 commits): qpvuntsm 1eb845f3 (empty) commit [EOF] "); // Untracked remote bookmark shouldn't block creation of local bookmark work_dir .run_jj(["bookmark", "untrack", "foo@origin"]) .success(); work_dir.run_jj(["bookmark", "delete", "foo"]).success(); let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to mzvwutvl 66d48752 foo | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" foo: mzvwutvl 66d48752 (empty) (no description set) foo@origin: qpvuntsm 1eb845f3 (empty) commit [EOF] ");} #[test]fn test_bookmark_move_matching() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir .run_jj(["bookmark", "create", "-r@", "a1", "a2"]) .success(); work_dir.run_jj(["new", "-mhead1"]).success(); work_dir.run_jj(["new", "root()"]).success(); work_dir .run_jj(["bookmark", "create", "-r@", "b1"]) .success(); work_dir.run_jj(["new"]).success(); work_dir .run_jj(["bookmark", "create", "-r@", "c1"]) .success(); work_dir.run_jj(["new", "-mhead2"]).success(); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ a2781dd9ee37 ○ c1 f4f38657a3dd ○ b1 f652c32197cf │ ○ 6b5e840ea72b │ ○ a1 a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] "); // The default could be considered "--from=all() glob:*", but is disabled let output = work_dir.run_jj(["bookmark", "move", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the following required arguments were not provided: <--from <REVSETS>|NAMES> Usage: jj bookmark move --to <REVSET> <--from <REVSETS>|NAMES> For more information, try '--help'. [EOF] [exit status: 2] "); // No bookmarks pointing to the source revisions let output = work_dir.run_jj(["bookmark", "move", "--from=none()", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- No bookmarks to update. [EOF] "); // No matching bookmarks within the source revisions let output = work_dir.run_jj(["bookmark", "move", "--from=::@", "glob:a?", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: No matching bookmarks for patterns: a? [EOF] [exit status: 1] "); // Noop move let output = work_dir.run_jj(["bookmark", "move", "--to=a1", "a2"]); insta::assert_snapshot!(output, @r" ------- stderr ------- No bookmarks to update. [EOF] "); // Move from multiple revisions let output = work_dir.run_jj(["bookmark", "move", "--from=::@", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 2 bookmarks to vruxwmqv a2781dd9 b1 c1 | (empty) head2 Hint: Specify bookmark by name to update just one of the bookmarks. [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ b1 c1 a2781dd9ee37 ○ f4f38657a3dd ○ f652c32197cf │ ○ 6b5e840ea72b │ ○ a1 a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] "); work_dir.run_jj(["undo"]).success(); // Try to move multiple bookmarks, but one of them isn't fast-forward let output = work_dir.run_jj(["bookmark", "move", "glob:?1", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Refusing to move bookmark backwards or sideways: a1 Hint: Use --allow-backwards to allow it. [EOF] [exit status: 1] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ a2781dd9ee37 ○ c1 f4f38657a3dd ○ b1 f652c32197cf │ ○ 6b5e840ea72b │ ○ a1 a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] "); // Select by revision and name let output = work_dir.run_jj(["bookmark", "move", "--from=::a1+", "--to=a1+", "glob:?1"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to kkmpptxz 6b5e840e a1 | (empty) head1 [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ a2781dd9ee37 ○ c1 f4f38657a3dd ○ b1 f652c32197cf │ ○ a1 6b5e840ea72b │ ○ a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] ");Lines 1–500 of 2285. Load more
// Copyright 2022 The Jujutsu Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use testutils::git; use crate::common::CommandOutput; use crate::common::TestEnvironment; use crate::common::TestWorkDir; fn create_commit_with_refs( repo: &gix::Repository, message: &str, content: &[u8], ref_names: &[&str], ) { let git::CommitResult { tree_id: _, commit_id, } = git::add_commit(repo, "refs/heads/dummy", "file", content, message, &[]); repo.find_reference("dummy").unwrap().delete().unwrap(); for name in ref_names { repo.reference( *name, commit_id, gix::refs::transaction::PreviousValue::Any, "log message", ) .unwrap(); } } #[test] fn test_bookmark_multiple_names() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo", "bar"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 2 bookmarks pointing to qpvuntsm 230dd059 bar foo | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ bar foo 230dd059e1b0 ◆ 000000000000 [EOF] "); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["bookmark", "set", "foo", "bar", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 2 bookmarks to zsuskuln 8bb159bc bar foo | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ bar foo 8bb159bc30a9 ○ 230dd059e1b0 ◆ 000000000000 [EOF] "); let output = work_dir.run_jj(["bookmark", "delete", "foo", "bar", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Deleted 2 bookmarks. [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ 8bb159bc30a9 ○ 230dd059e1b0 ◆ 000000000000 [EOF] "); // Hint should be omitted if -r is specified let output = work_dir.run_jj(["bookmark", "create", "-r@-", "foo", "bar"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 2 bookmarks pointing to qpvuntsm 230dd059 bar foo | (empty) (no description set) [EOF] "); // Create and move with explicit -r let output = work_dir.run_jj(["bookmark", "set", "-r@", "bar", "baz"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to zsuskuln 8bb159bc bar baz | (empty) (no description set) Moved 1 bookmarks to zsuskuln 8bb159bc bar baz | (empty) (no description set) [EOF] "); // Noop changes should not be included in the stats let output = work_dir.run_jj(["bookmark", "set", "-r@", "foo", "bar", "baz"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to zsuskuln 8bb159bc bar baz foo | (empty) (no description set) [EOF] "); } #[test] fn test_bookmark_at_root() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["bookmark", "create", "fred", "-r=root()"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to zzzzzzzz 00000000 fred | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["git", "export"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. Warning: Failed to export some bookmarks: fred@git: Ref cannot point to the root commit in Git [EOF] "); } #[test] fn test_bookmark_bad_name() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); let output = work_dir.run_jj(["bookmark", "create", "-r@", ""]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '' for '<NAMES>...': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:1 | 1 | | ^--- | = expected <identifier>, <string_literal>, or <raw_string_literal> Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); let output = work_dir.run_jj(["bookmark", "set", "''"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '''' for '<NAMES>...': Failed to parse bookmark name: Expected non-empty string For more information, try '--help'. Caused by: --> 1:1 | 1 | '' | ^^ | = Expected non-empty string Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); let output = work_dir.run_jj(["bookmark", "rename", "x", ""]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '' for '<NEW>': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:1 | 1 | | ^--- | = expected <identifier>, <string_literal>, or <raw_string_literal> Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); // common errors let output = work_dir.run_jj(["bookmark", "set", "@-", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: invalid value '@-' for '<NAMES>...': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:1 | 1 | @- | ^--- | = expected <identifier>, <string_literal>, or <raw_string_literal> Hint: See https://jj-vcs.github.io/jj/latest/revsets/ or use `jj help -k revsets` for how to quote symbols. [EOF] [exit status: 2] "); let stderr = work_dir.run_jj(["bookmark", "set", "-r@-", "foo@bar"]); insta::assert_snapshot!(stderr, @r" ------- stderr ------- error: invalid value 'foo@bar' for '<NAMES>...': Failed to parse bookmark name: Syntax error For more information, try '--help'. Caused by: --> 1:4 | 1 | foo@bar | ^--- | = expected <EOI> Hint: Looks like remote bookmark. Run `jj bookmark track foo@bar` to track it. [EOF] [exit status: 2] "); // quoted name works let output = work_dir.run_jj(["bookmark", "create", "-r@", "'foo@bar'"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to qpvuntsm 230dd059 foo@bar | (empty) (no description set) [EOF] "); } #[test] fn test_bookmark_move() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); // Set up remote let git_repo_path = test_env.env_root().join("git-repo"); git::init_bare(git_repo_path); work_dir .run_jj(["git", "remote", "add", "origin", "../git-repo"]) .success(); let output = work_dir.run_jj(["bookmark", "move", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: No such bookmark: foo [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "set", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to qpvuntsm 230dd059 foo | (empty) (no description set) [EOF] "); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Bookmark already exists: foo Hint: Use `jj bookmark set` to update it. [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "set", "foo", "--revision", "@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to mzvwutvl 167f90e7 foo | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["bookmark", "set", "-r@-", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Refusing to move bookmark backwards or sideways: foo Hint: Use --allow-backwards to allow it. [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "set", "-r@-", "--allow-backwards", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to qpvuntsm 230dd059 foo | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["bookmark", "move", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to mzvwutvl 167f90e7 foo | (empty) (no description set) [EOF] "); let output = work_dir.run_jj(["bookmark", "move", "--to=@-", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Refusing to move bookmark backwards or sideways: foo Hint: Use --allow-backwards to allow it. [EOF] [exit status: 1] "); let output = work_dir.run_jj(["bookmark", "move", "--to=@-", "--allow-backwards", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to qpvuntsm 230dd059 foo | (empty) (no description set) [EOF] "); // Delete bookmark locally, but is still tracking remote work_dir.run_jj(["describe", "@-", "-mcommit"]).success(); work_dir .run_jj(["git", "push", "--allow-new", "-r@-"]) .success(); work_dir.run_jj(["bookmark", "delete", "foo"]).success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" foo (deleted) @origin: qpvuntsm 1eb845f3 (empty) commit [EOF] "); // Deleted tracking bookmark name should still be allocated let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Tracked remote bookmarks exist for deleted bookmark: foo Hint: Use `jj bookmark set` to recreate the local bookmark. Run `jj bookmark untrack 'glob:foo@*'` to disassociate them. [EOF] [exit status: 1] "); // Restoring local target shouldn't invalidate tracking state let output = work_dir.run_jj(["bookmark", "set", "foo", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to mzvwutvl 66d48752 foo* | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" foo: mzvwutvl 66d48752 (empty) (no description set) @origin (behind by 1 commits): qpvuntsm 1eb845f3 (empty) commit [EOF] "); // Untracked remote bookmark shouldn't block creation of local bookmark work_dir .run_jj(["bookmark", "untrack", "foo@origin"]) .success(); work_dir.run_jj(["bookmark", "delete", "foo"]).success(); let output = work_dir.run_jj(["bookmark", "create", "-r@", "foo"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Created 1 bookmarks pointing to mzvwutvl 66d48752 foo | (empty) (no description set) [EOF] "); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" foo: mzvwutvl 66d48752 (empty) (no description set) foo@origin: qpvuntsm 1eb845f3 (empty) commit [EOF] "); } #[test] fn test_bookmark_move_matching() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "repo"]).success(); let work_dir = test_env.work_dir("repo"); work_dir .run_jj(["bookmark", "create", "-r@", "a1", "a2"]) .success(); work_dir.run_jj(["new", "-mhead1"]).success(); work_dir.run_jj(["new", "root()"]).success(); work_dir .run_jj(["bookmark", "create", "-r@", "b1"]) .success(); work_dir.run_jj(["new"]).success(); work_dir .run_jj(["bookmark", "create", "-r@", "c1"]) .success(); work_dir.run_jj(["new", "-mhead2"]).success(); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ a2781dd9ee37 ○ c1 f4f38657a3dd ○ b1 f652c32197cf │ ○ 6b5e840ea72b │ ○ a1 a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] "); // The default could be considered "--from=all() glob:*", but is disabled let output = work_dir.run_jj(["bookmark", "move", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- error: the following required arguments were not provided: <--from <REVSETS>|NAMES> Usage: jj bookmark move --to <REVSET> <--from <REVSETS>|NAMES> For more information, try '--help'. [EOF] [exit status: 2] "); // No bookmarks pointing to the source revisions let output = work_dir.run_jj(["bookmark", "move", "--from=none()", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- No bookmarks to update. [EOF] "); // No matching bookmarks within the source revisions let output = work_dir.run_jj(["bookmark", "move", "--from=::@", "glob:a?", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: No matching bookmarks for patterns: a? [EOF] [exit status: 1] "); // Noop move let output = work_dir.run_jj(["bookmark", "move", "--to=a1", "a2"]); insta::assert_snapshot!(output, @r" ------- stderr ------- No bookmarks to update. [EOF] "); // Move from multiple revisions let output = work_dir.run_jj(["bookmark", "move", "--from=::@", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 2 bookmarks to vruxwmqv a2781dd9 b1 c1 | (empty) head2 Hint: Specify bookmark by name to update just one of the bookmarks. [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ b1 c1 a2781dd9ee37 ○ f4f38657a3dd ○ f652c32197cf │ ○ 6b5e840ea72b │ ○ a1 a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] "); work_dir.run_jj(["undo"]).success(); // Try to move multiple bookmarks, but one of them isn't fast-forward let output = work_dir.run_jj(["bookmark", "move", "glob:?1", "--to=@"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Error: Refusing to move bookmark backwards or sideways: a1 Hint: Use --allow-backwards to allow it. [EOF] [exit status: 1] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ a2781dd9ee37 ○ c1 f4f38657a3dd ○ b1 f652c32197cf │ ○ 6b5e840ea72b │ ○ a1 a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] "); // Select by revision and name let output = work_dir.run_jj(["bookmark", "move", "--from=::a1+", "--to=a1+", "glob:?1"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Moved 1 bookmarks to kkmpptxz 6b5e840e a1 | (empty) head1 [EOF] "); insta::assert_snapshot!(get_log_output(&work_dir), @r" @ a2781dd9ee37 ○ c1 f4f38657a3dd ○ b1 f652c32197cf │ ○ a1 6b5e840ea72b │ ○ a2 230dd059e1b0 ├─╯ ◆ 000000000000 [EOF] ");