// 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 std::path::Path;use std::path::PathBuf; use crate::common::TestEnvironment; fn set_up() -> (TestEnvironment, PathBuf) { let test_env = TestEnvironment::default(); test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "origin"]); let origin_path = test_env.env_root().join("origin"); let origin_git_repo_path = origin_path .join(".jj") .join("repo") .join("store") .join("git"); test_env.jj_cmd_ok(&origin_path, &["describe", "-m=description 1"]); test_env.jj_cmd_ok(&origin_path, &["bookmark", "create", "bookmark1"]); test_env.jj_cmd_ok(&origin_path, &["new", "root()", "-m=description 2"]); test_env.jj_cmd_ok(&origin_path, &["bookmark", "create", "bookmark2"]); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); test_env.jj_cmd_ok( test_env.env_root(), &[ "git", "clone", "--config-toml=git.auto-local-bookmark=true", origin_git_repo_path.to_str().unwrap(), "local", ], ); let workspace_root = test_env.env_root().join("local"); (test_env, workspace_root)} #[test]fn test_git_push_nothing() { let (test_env, workspace_root) = set_up(); // Show the setup. `insta` has trouble if this is done inside `set_up()` insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv d13ecdbd (empty) description 1 @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); // No bookmarks to push yet let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Nothing changed. "###);} #[test]fn test_git_push_current_bookmark() { let (test_env, workspace_root) = set_up(); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); // Update some bookmarks. `bookmark1` is not a current bookmark, but // `bookmark2` and `my-bookmark` are. test_env.jj_cmd_ok( &workspace_root, &["describe", "bookmark1", "-m", "modified bookmark1 commit"], ); test_env.jj_cmd_ok(&workspace_root, &["new", "bookmark2"]); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "set", "bookmark2"]); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "my-bookmark"]); test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]); // Check the setup insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv 0f8dc656 (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv hidden d13ecdbd (empty) description 1 bookmark2: yostqsxw bc7610b6 (empty) foo @origin (behind by 1 commits): rlzusymt 8476341e (empty) description 2 my-bookmark: yostqsxw bc7610b6 (empty) foo "###); // First dry-run. `bookmark1` should not get pushed. let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--dry-run"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move forward bookmark bookmark2 from 8476341eb395 to bc7610b65a91 Add bookmark my-bookmark to bc7610b65a91 Dry-run requested, not pushing. "#); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move forward bookmark bookmark2 from 8476341eb395 to bc7610b65a91 Add bookmark my-bookmark to bc7610b65a91 "#); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv 0f8dc656 (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv hidden d13ecdbd (empty) description 1 bookmark2: yostqsxw bc7610b6 (empty) foo @origin: yostqsxw bc7610b6 (empty) foo my-bookmark: yostqsxw bc7610b6 (empty) foo @origin: yostqsxw bc7610b6 (empty) foo "###); // Try pushing backwards test_env.jj_cmd_ok( &workspace_root, &[ "bookmark", "set", "bookmark2", "-rbookmark2-", "--allow-backwards", ], ); // This behavior is a strangeness of our definition of the default push revset. // We could consider changing it. let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###); // We can move a bookmark backwards let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-bbookmark2"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move backward bookmark bookmark2 from bc7610b65a91 to 8476341eb395 "#);} #[test]fn test_git_push_parent_bookmark() { let (test_env, workspace_root) = set_up(); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); test_env.jj_cmd_ok(&workspace_root, &["edit", "bookmark1"]); test_env.jj_cmd_ok( &workspace_root, &["describe", "-m", "modified bookmark1 commit"], ); test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "non-empty description"]); std::fs::write(workspace_root.join("file"), "file").unwrap(); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to e612d524a5c6 "#);} #[test]fn test_git_push_no_matching_bookmark() { let (test_env, workspace_root) = set_up(); test_env.jj_cmd_ok(&workspace_root, &["new"]); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###);} #[test]fn test_git_push_matching_bookmark_unchanged() { let (test_env, workspace_root) = set_up(); test_env.jj_cmd_ok(&workspace_root, &["new", "bookmark1"]); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###);} /// Test that `jj git push` without arguments pushes a bookmark to the specified/// remote even if it's already up to date on another remote/// (`remote_bookmarks(remote=<remote>)..@` vs. `remote_bookmarks()..@`).#[test]fn test_git_push_other_remote_has_bookmark() { let (test_env, workspace_root) = set_up(); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); // Create another remote (but actually the same) let other_remote_path = test_env .env_root() .join("origin") .join(".jj") .join("repo") .join("store") .join("git"); test_env.jj_cmd_ok( &workspace_root, &[ "git", "remote", "add", "other", other_remote_path.to_str().unwrap(), ], ); // Modify bookmark1 and push it to `origin` test_env.jj_cmd_ok(&workspace_root, &["edit", "bookmark1"]); test_env.jj_cmd_ok(&workspace_root, &["describe", "-m=modified"]); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to a657f1b61b94 "#); // Since it's already pushed to origin, nothing will happen if push again let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###); // The bookmark was moved on the "other" remote as well (since it's actually the // same remote), but `jj` is not aware of that since it thinks this is a // different remote. So, the push should fail. // // But it succeeds! That's because the bookmark is created at the same location // as it is on the remote. This would also work for a descendant. // // TODO: Saner test? let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--remote=other"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to other: Add bookmark bookmark1 to a657f1b61b94 "#);} #[test]fn test_git_push_forward_unexpectedly_moved() { let (test_env, workspace_root) = set_up(); // Move bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["new", "bookmark1", "-m=remote"]); std::fs::write(origin_path.join("remote"), "remote").unwrap(); test_env.jj_cmd_ok(&origin_path, &["bookmark", "set", "bookmark1"]); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Move bookmark1 forward to another commit locally test_env.jj_cmd_ok(&workspace_root, &["new", "bookmark1", "-m=local"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "set", "bookmark1"]); // Pushing should fail let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move forward bookmark bookmark1 from d13ecdbda2a2 to 6750425ff51c Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#);} #[test]fn test_git_push_sideways_unexpectedly_moved() { let (test_env, workspace_root) = set_up(); // Move bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["new", "bookmark1", "-m=remote"]); std::fs::write(origin_path.join("remote"), "remote").unwrap(); test_env.jj_cmd_ok(&origin_path, &["bookmark", "set", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &origin_path), @r###" bookmark1: vruxwmqv 80284bec remote @git (behind by 1 commits): qpvuntsm d13ecdbd (empty) description 1 bookmark2: zsuskuln 8476341e (empty) description 2 @git: zsuskuln 8476341e (empty) description 2 "###); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Move bookmark1 sideways to another commit locally test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-m=local"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok( &workspace_root, &["bookmark", "set", "bookmark1", "--allow-backwards"], ); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: kmkuslsw 0f8bf988 local @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to 0f8bf988588e Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#);} // This tests whether the push checks that the remote bookmarks are in expected// positions.#[test]fn test_git_push_deletion_unexpectedly_moved() { let (test_env, workspace_root) = set_up(); // Move bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["new", "bookmark1", "-m=remote"]); std::fs::write(origin_path.join("remote"), "remote").unwrap(); test_env.jj_cmd_ok(&origin_path, &["bookmark", "set", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &origin_path), @r###" bookmark1: vruxwmqv 80284bec remote @git (behind by 1 commits): qpvuntsm d13ecdbd (empty) description 1 bookmark2: zsuskuln 8476341e (empty) description 2 @git: zsuskuln 8476341e (empty) description 2 "###); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Delete bookmark1 locally test_env.jj_cmd_ok(&workspace_root, &["bookmark", "delete", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1 (deleted) @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--bookmark", "bookmark1"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#);} #[test]fn test_git_push_unexpectedly_deleted() { let (test_env, workspace_root) = set_up(); // Delete bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["bookmark", "delete", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &origin_path), @r###" bookmark1 (deleted) @git: qpvuntsm d13ecdbd (empty) description 1 bookmark2: zsuskuln 8476341e (empty) description 2 @git: zsuskuln 8476341e (empty) description 2 "###); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Move bookmark1 sideways to another commit locally test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-m=local"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok( &workspace_root, &["bookmark", "set", "bookmark1", "--allow-backwards"], ); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: kpqxywon 1ebe27ba local @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); // Pushing a moved bookmark fails if deleted on remote let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to 1ebe27ba04bf Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "delete", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1 (deleted) @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); // Pushing a *deleted* bookmark succeeds if deleted on remote, even if we expect // bookmark1@origin to exist and point somewhere. let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-bbookmark1"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 "#);} #[test]fn test_git_push_creation_unexpectedly_already_exists() { let (test_env, workspace_root) = set_up(); // Forget bookmark1 locally test_env.jj_cmd_ok(&workspace_root, &["bookmark", "forget", "bookmark1"]); // Create a new branh1 test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-m=new bookmark1"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: yostqsxw cb17dcdc new bookmark1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Add bookmark bookmark1 to cb17dcdc74d5 Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#);} #[test]fn test_git_push_locally_created_and_rewritten() { let (test_env, workspace_root) = set_up(); // Ensure that remote bookmarks aren't tracked automatically test_env.add_config("git.auto-local-bookmark = false"); // Push locally-created bookmark test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-mlocal 1"]); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "my"]); let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Add bookmark my to fcc999921ce9 "#); // Rewrite it and push again, which would fail if the pushed bookmark weren't // set to "tracking" test_env.jj_cmd_ok(&workspace_root, &["describe", "-mlocal 2"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv d13ecdbd (empty) description 1 @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 my: vruxwmqv bde1d2e4 (empty) local 2 @origin (ahead by 1 commits, behind by 1 commits): vruxwmqv hidden fcc99992 (empty) local 1 "###); let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark my from fcc999921ce9 to bde1d2e44b2a "#);} #[test]fn test_git_push_multiple() { let (test_env, workspace_root) = set_up(); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "delete", "bookmark1"]); test_env.jj_cmd_ok( &workspace_root, &["bookmark", "set", "--allow-backwards", "bookmark2"], ); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "my-bookmark"]); test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]); // Check the setup insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1 (deleted) @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: yqosqzyt c4a3c310 (empty) foo @origin (ahead by 1 commits, behind by 1 commits): rlzusymt 8476341e (empty) description 2 my-bookmark: yqosqzyt c4a3c310 (empty) foo "###); // First dry-run let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all", "--dry-run"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 Move sideways bookmark bookmark2 from 8476341eb395 to c4a3c3105d92 Add bookmark my-bookmark to c4a3c3105d92 Dry-run requested, not pushing. "#); // Dry run requesting two specific bookmarks let (stdout, stderr) = test_env.jj_cmd_ok( &workspace_root, &["git", "push", "-b=bookmark1", "-b=my-bookmark", "--dry-run"], ); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 Add bookmark my-bookmark to c4a3c3105d92 Dry-run requested, not pushing.Lines 1–500 of 1317. 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 std::path::Path; use std::path::PathBuf; use crate::common::TestEnvironment; fn set_up() -> (TestEnvironment, PathBuf) { let test_env = TestEnvironment::default(); test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "origin"]); let origin_path = test_env.env_root().join("origin"); let origin_git_repo_path = origin_path .join(".jj") .join("repo") .join("store") .join("git"); test_env.jj_cmd_ok(&origin_path, &["describe", "-m=description 1"]); test_env.jj_cmd_ok(&origin_path, &["bookmark", "create", "bookmark1"]); test_env.jj_cmd_ok(&origin_path, &["new", "root()", "-m=description 2"]); test_env.jj_cmd_ok(&origin_path, &["bookmark", "create", "bookmark2"]); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); test_env.jj_cmd_ok( test_env.env_root(), &[ "git", "clone", "--config-toml=git.auto-local-bookmark=true", origin_git_repo_path.to_str().unwrap(), "local", ], ); let workspace_root = test_env.env_root().join("local"); (test_env, workspace_root) } #[test] fn test_git_push_nothing() { let (test_env, workspace_root) = set_up(); // Show the setup. `insta` has trouble if this is done inside `set_up()` insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv d13ecdbd (empty) description 1 @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); // No bookmarks to push yet let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Nothing changed. "###); } #[test] fn test_git_push_current_bookmark() { let (test_env, workspace_root) = set_up(); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); // Update some bookmarks. `bookmark1` is not a current bookmark, but // `bookmark2` and `my-bookmark` are. test_env.jj_cmd_ok( &workspace_root, &["describe", "bookmark1", "-m", "modified bookmark1 commit"], ); test_env.jj_cmd_ok(&workspace_root, &["new", "bookmark2"]); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "set", "bookmark2"]); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "my-bookmark"]); test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]); // Check the setup insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv 0f8dc656 (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv hidden d13ecdbd (empty) description 1 bookmark2: yostqsxw bc7610b6 (empty) foo @origin (behind by 1 commits): rlzusymt 8476341e (empty) description 2 my-bookmark: yostqsxw bc7610b6 (empty) foo "###); // First dry-run. `bookmark1` should not get pushed. let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--dry-run"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move forward bookmark bookmark2 from 8476341eb395 to bc7610b65a91 Add bookmark my-bookmark to bc7610b65a91 Dry-run requested, not pushing. "#); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move forward bookmark bookmark2 from 8476341eb395 to bc7610b65a91 Add bookmark my-bookmark to bc7610b65a91 "#); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv 0f8dc656 (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv hidden d13ecdbd (empty) description 1 bookmark2: yostqsxw bc7610b6 (empty) foo @origin: yostqsxw bc7610b6 (empty) foo my-bookmark: yostqsxw bc7610b6 (empty) foo @origin: yostqsxw bc7610b6 (empty) foo "###); // Try pushing backwards test_env.jj_cmd_ok( &workspace_root, &[ "bookmark", "set", "bookmark2", "-rbookmark2-", "--allow-backwards", ], ); // This behavior is a strangeness of our definition of the default push revset. // We could consider changing it. let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###); // We can move a bookmark backwards let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-bbookmark2"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move backward bookmark bookmark2 from bc7610b65a91 to 8476341eb395 "#); } #[test] fn test_git_push_parent_bookmark() { let (test_env, workspace_root) = set_up(); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); test_env.jj_cmd_ok(&workspace_root, &["edit", "bookmark1"]); test_env.jj_cmd_ok( &workspace_root, &["describe", "-m", "modified bookmark1 commit"], ); test_env.jj_cmd_ok(&workspace_root, &["new", "-m", "non-empty description"]); std::fs::write(workspace_root.join("file"), "file").unwrap(); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to e612d524a5c6 "#); } #[test] fn test_git_push_no_matching_bookmark() { let (test_env, workspace_root) = set_up(); test_env.jj_cmd_ok(&workspace_root, &["new"]); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###); } #[test] fn test_git_push_matching_bookmark_unchanged() { let (test_env, workspace_root) = set_up(); test_env.jj_cmd_ok(&workspace_root, &["new", "bookmark1"]); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###); } /// Test that `jj git push` without arguments pushes a bookmark to the specified /// remote even if it's already up to date on another remote /// (`remote_bookmarks(remote=<remote>)..@` vs. `remote_bookmarks()..@`). #[test] fn test_git_push_other_remote_has_bookmark() { let (test_env, workspace_root) = set_up(); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); // Create another remote (but actually the same) let other_remote_path = test_env .env_root() .join("origin") .join(".jj") .join("repo") .join("store") .join("git"); test_env.jj_cmd_ok( &workspace_root, &[ "git", "remote", "add", "other", other_remote_path.to_str().unwrap(), ], ); // Modify bookmark1 and push it to `origin` test_env.jj_cmd_ok(&workspace_root, &["edit", "bookmark1"]); test_env.jj_cmd_ok(&workspace_root, &["describe", "-m=modified"]); let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to a657f1b61b94 "#); // Since it's already pushed to origin, nothing will happen if push again let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r###" Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. "###); // The bookmark was moved on the "other" remote as well (since it's actually the // same remote), but `jj` is not aware of that since it thinks this is a // different remote. So, the push should fail. // // But it succeeds! That's because the bookmark is created at the same location // as it is on the remote. This would also work for a descendant. // // TODO: Saner test? let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--remote=other"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to other: Add bookmark bookmark1 to a657f1b61b94 "#); } #[test] fn test_git_push_forward_unexpectedly_moved() { let (test_env, workspace_root) = set_up(); // Move bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["new", "bookmark1", "-m=remote"]); std::fs::write(origin_path.join("remote"), "remote").unwrap(); test_env.jj_cmd_ok(&origin_path, &["bookmark", "set", "bookmark1"]); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Move bookmark1 forward to another commit locally test_env.jj_cmd_ok(&workspace_root, &["new", "bookmark1", "-m=local"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "set", "bookmark1"]); // Pushing should fail let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move forward bookmark bookmark1 from d13ecdbda2a2 to 6750425ff51c Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#); } #[test] fn test_git_push_sideways_unexpectedly_moved() { let (test_env, workspace_root) = set_up(); // Move bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["new", "bookmark1", "-m=remote"]); std::fs::write(origin_path.join("remote"), "remote").unwrap(); test_env.jj_cmd_ok(&origin_path, &["bookmark", "set", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &origin_path), @r###" bookmark1: vruxwmqv 80284bec remote @git (behind by 1 commits): qpvuntsm d13ecdbd (empty) description 1 bookmark2: zsuskuln 8476341e (empty) description 2 @git: zsuskuln 8476341e (empty) description 2 "###); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Move bookmark1 sideways to another commit locally test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-m=local"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok( &workspace_root, &["bookmark", "set", "bookmark1", "--allow-backwards"], ); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: kmkuslsw 0f8bf988 local @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to 0f8bf988588e Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#); } // This tests whether the push checks that the remote bookmarks are in expected // positions. #[test] fn test_git_push_deletion_unexpectedly_moved() { let (test_env, workspace_root) = set_up(); // Move bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["new", "bookmark1", "-m=remote"]); std::fs::write(origin_path.join("remote"), "remote").unwrap(); test_env.jj_cmd_ok(&origin_path, &["bookmark", "set", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &origin_path), @r###" bookmark1: vruxwmqv 80284bec remote @git (behind by 1 commits): qpvuntsm d13ecdbd (empty) description 1 bookmark2: zsuskuln 8476341e (empty) description 2 @git: zsuskuln 8476341e (empty) description 2 "###); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Delete bookmark1 locally test_env.jj_cmd_ok(&workspace_root, &["bookmark", "delete", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1 (deleted) @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push", "--bookmark", "bookmark1"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#); } #[test] fn test_git_push_unexpectedly_deleted() { let (test_env, workspace_root) = set_up(); // Delete bookmark1 forward on the remote let origin_path = test_env.env_root().join("origin"); test_env.jj_cmd_ok(&origin_path, &["bookmark", "delete", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &origin_path), @r###" bookmark1 (deleted) @git: qpvuntsm d13ecdbd (empty) description 1 bookmark2: zsuskuln 8476341e (empty) description 2 @git: zsuskuln 8476341e (empty) description 2 "###); test_env.jj_cmd_ok(&origin_path, &["git", "export"]); // Move bookmark1 sideways to another commit locally test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-m=local"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok( &workspace_root, &["bookmark", "set", "bookmark1", "--allow-backwards"], ); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: kpqxywon 1ebe27ba local @origin (ahead by 1 commits, behind by 1 commits): xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); // Pushing a moved bookmark fails if deleted on remote let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark bookmark1 from d13ecdbda2a2 to 1ebe27ba04bf Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "delete", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1 (deleted) @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); // Pushing a *deleted* bookmark succeeds if deleted on remote, even if we expect // bookmark1@origin to exist and point somewhere. let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "-bbookmark1"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 "#); } #[test] fn test_git_push_creation_unexpectedly_already_exists() { let (test_env, workspace_root) = set_up(); // Forget bookmark1 locally test_env.jj_cmd_ok(&workspace_root, &["bookmark", "forget", "bookmark1"]); // Create a new branh1 test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-m=new bookmark1"]); std::fs::write(workspace_root.join("local"), "local").unwrap(); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "bookmark1"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: yostqsxw cb17dcdc new bookmark1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 "###); let stderr = test_env.jj_cmd_failure(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Add bookmark bookmark1 to cb17dcdc74d5 Error: Refusing to push a bookmark that unexpectedly moved on the remote. Affected refs: refs/heads/bookmark1 Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. "#); } #[test] fn test_git_push_locally_created_and_rewritten() { let (test_env, workspace_root) = set_up(); // Ensure that remote bookmarks aren't tracked automatically test_env.add_config("git.auto-local-bookmark = false"); // Push locally-created bookmark test_env.jj_cmd_ok(&workspace_root, &["new", "root()", "-mlocal 1"]); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "my"]); let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Add bookmark my to fcc999921ce9 "#); // Rewrite it and push again, which would fail if the pushed bookmark weren't // set to "tracking" test_env.jj_cmd_ok(&workspace_root, &["describe", "-mlocal 2"]); insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1: xtvrqkyv d13ecdbd (empty) description 1 @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: rlzusymt 8476341e (empty) description 2 @origin: rlzusymt 8476341e (empty) description 2 my: vruxwmqv bde1d2e4 (empty) local 2 @origin (ahead by 1 commits, behind by 1 commits): vruxwmqv hidden fcc99992 (empty) local 1 "###); let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push"]); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Move sideways bookmark my from fcc999921ce9 to bde1d2e44b2a "#); } #[test] fn test_git_push_multiple() { let (test_env, workspace_root) = set_up(); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "delete", "bookmark1"]); test_env.jj_cmd_ok( &workspace_root, &["bookmark", "set", "--allow-backwards", "bookmark2"], ); test_env.jj_cmd_ok(&workspace_root, &["bookmark", "create", "my-bookmark"]); test_env.jj_cmd_ok(&workspace_root, &["describe", "-m", "foo"]); // Check the setup insta::assert_snapshot!(get_bookmark_output(&test_env, &workspace_root), @r###" bookmark1 (deleted) @origin: xtvrqkyv d13ecdbd (empty) description 1 bookmark2: yqosqzyt c4a3c310 (empty) foo @origin (ahead by 1 commits, behind by 1 commits): rlzusymt 8476341e (empty) description 2 my-bookmark: yqosqzyt c4a3c310 (empty) foo "###); // First dry-run let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "push", "--all", "--dry-run"]); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 Move sideways bookmark bookmark2 from 8476341eb395 to c4a3c3105d92 Add bookmark my-bookmark to c4a3c3105d92 Dry-run requested, not pushing. "#); // Dry run requesting two specific bookmarks let (stdout, stderr) = test_env.jj_cmd_ok( &workspace_root, &["git", "push", "-b=bookmark1", "-b=my-bookmark", "--dry-run"], ); insta::assert_snapshot!(stdout, @""); insta::assert_snapshot!(stderr, @r#" Changes to push to origin: Delete bookmark bookmark1 from d13ecdbda2a2 Add bookmark my-bookmark to c4a3c3105d92 Dry-run requested, not pushing.