// 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::to_toml_value;use crate::common::CommandOutput;use crate::common::TestEnvironment;use crate::common::TestWorkDir; fn git_repo_dir_for_jj_repo(work_dir: &TestWorkDir<'_>) -> std::path::PathBuf { work_dir .root() .join(".jj") .join("repo") .join("store") .join("git")} fn set_up(test_env: &TestEnvironment) { test_env.run_jj_in(".", ["git", "init", "origin"]).success(); let origin_dir = test_env.work_dir("origin"); let origin_git_repo_path = git_repo_dir_for_jj_repo(&origin_dir); origin_dir .run_jj(["describe", "-m=description 1"]) .success(); origin_dir .run_jj(["bookmark", "create", "-r@", "bookmark1"]) .success(); origin_dir .run_jj(["new", "root()", "-m=description 2"]) .success(); origin_dir .run_jj(["bookmark", "create", "-r@", "bookmark2"]) .success(); origin_dir.run_jj(["git", "export"]).success(); test_env .run_jj_in( ".", [ "git", "clone", "--config=git.auto-local-bookmark=true", origin_git_repo_path.to_str().unwrap(), "local", ], ) .success();} #[test]fn test_git_push_nothing() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Show the setup. `insta` has trouble if this is done inside `set_up()` insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: qpvuntsm 9b2e76de (empty) description 1 @origin: qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); // No bookmarks to push yet let output = work_dir.run_jj(["git", "push", "--all"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. [EOF] ");} #[test]fn test_git_push_current_bookmark() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); 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. work_dir .run_jj(["describe", "bookmark1", "-m", "modified bookmark1 commit"]) .success(); work_dir.run_jj(["new", "bookmark2"]).success(); work_dir .run_jj(["bookmark", "set", "bookmark2", "-r@"]) .success(); work_dir .run_jj(["bookmark", "create", "-r@", "my-bookmark"]) .success(); work_dir.run_jj(["describe", "-m", "foo"]).success(); // Check the setup insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: qpvuntsm e5ce6d9a (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 9b2e76de (empty) description 1 bookmark2: yostqsxw 88ca14a7 (empty) foo @origin (behind by 1 commits): zsuskuln 38a20473 (empty) description 2 my-bookmark: yostqsxw 88ca14a7 (empty) foo [EOF] "); // First dry-run. `bookmark1` should not get pushed. let output = work_dir.run_jj(["git", "push", "--allow-new", "--dry-run"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark2 from 38a204733702 to 88ca14a7d46f Add bookmark my-bookmark to 88ca14a7d46f Dry-run requested, not pushing. [EOF] "); let output = work_dir.run_jj(["git", "push", "--allow-new"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark2 from 38a204733702 to 88ca14a7d46f Add bookmark my-bookmark to 88ca14a7d46f [EOF] "); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: qpvuntsm e5ce6d9a (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 9b2e76de (empty) description 1 bookmark2: yostqsxw 88ca14a7 (empty) foo @origin: yostqsxw 88ca14a7 (empty) foo my-bookmark: yostqsxw 88ca14a7 (empty) foo @origin: yostqsxw 88ca14a7 (empty) foo [EOF] "); // Try pushing backwards work_dir .run_jj([ "bookmark", "set", "bookmark2", "-rbookmark2-", "--allow-backwards", ]) .success(); // This behavior is a strangeness of our definition of the default push revset. // We could consider changing it. let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] "); // We can move a bookmark backwards let output = work_dir.run_jj(["git", "push", "-bbookmark2"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move backward bookmark bookmark2 from 88ca14a7d46f to 38a204733702 [EOF] ");} #[test]fn test_git_push_parent_bookmark() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); work_dir.run_jj(["edit", "bookmark1"]).success(); work_dir .run_jj(["describe", "-m", "modified bookmark1 commit"]) .success(); work_dir .run_jj(["new", "-m", "non-empty description"]) .success(); work_dir.write_file("file", "file"); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 80560a3e08e2 [EOF] ");} #[test]fn test_git_push_no_matching_bookmark() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] ");} #[test]fn test_git_push_matching_bookmark_unchanged() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); work_dir.run_jj(["new", "bookmark1"]).success(); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] ");} /// 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 = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); 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"); work_dir .run_jj([ "git", "remote", "add", "other", other_remote_path.to_str().unwrap(), ]) .success(); // Modify bookmark1 and push it to `origin` work_dir.run_jj(["edit", "bookmark1"]).success(); work_dir.run_jj(["describe", "-m=modified"]).success(); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to a843bfad2abb [EOF] "); // Since it's already pushed to origin, nothing will happen if push again let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] "); // 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 output = work_dir.run_jj(["git", "push", "--allow-new", "--remote=other"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to other: Add bookmark bookmark1 to a843bfad2abb [EOF] ");} #[test]fn test_git_push_forward_unexpectedly_moved() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Move bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["new", "bookmark1", "-m=remote"]) .success(); origin_dir.write_file("remote", "remote"); origin_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); origin_dir.run_jj(["git", "export"]).success(); // Move bookmark1 forward to another commit locally work_dir.run_jj(["new", "bookmark1", "-m=local"]).success(); work_dir.write_file("local", "local"); work_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); // Pushing should fail let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark1 from 9b2e76de3920 to 624f94a35f00 Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF] [exit status: 1] "); // The ref name should be colorized let output = work_dir.run_jj(["git", "push", "--color=always"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark1 from 9b2e76de3920 to 624f94a35f00 [1m[38;5;1mError: [39mFailed to push some bookmarks[0m [1m[38;5;6mHint: [0m[39mThe following references unexpectedly moved on the remote:[39m [39m [38;5;2mrefs/heads/bookmark1[39m (reason: stale info)[39m [1m[38;5;6mHint: [0m[39mTry fetching from the remote, then make the bookmark point to where you want it to be, and push again.[39m [EOF] [exit status: 1] ");} #[test]fn test_git_push_sideways_unexpectedly_moved() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Move bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["new", "bookmark1", "-m=remote"]) .success(); origin_dir.write_file("remote", "remote"); origin_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&origin_dir), @r" bookmark1: vruxwmqv 7ce4029e remote @git (behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @git: zsuskuln 38a20473 (empty) description 2 [EOF] "); origin_dir.run_jj(["git", "export"]).success(); // Move bookmark1 sideways to another commit locally work_dir.run_jj(["new", "root()", "-m=local"]).success(); work_dir.write_file("local", "local"); work_dir .run_jj(["bookmark", "set", "bookmark1", "--allow-backwards", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: kmkuslsw 827b8a38 local @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 827b8a385853 Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF] [exit status: 1] "); // The ref name should be colorized let output = work_dir.run_jj(["git", "push", "--color=always"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 827b8a385853 [1m[38;5;1mError: [39mFailed to push some bookmarks[0m [1m[38;5;6mHint: [0m[39mThe following references unexpectedly moved on the remote:[39m [39m [38;5;2mrefs/heads/bookmark1[39m (reason: stale info)[39m [1m[38;5;6mHint: [0m[39mTry fetching from the remote, then make the bookmark point to where you want it to be, and push again.[39m [EOF] [exit status: 1] ");} // 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 = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Move bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["new", "bookmark1", "-m=remote"]) .success(); origin_dir.write_file("remote", "remote"); origin_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&origin_dir), @r" bookmark1: vruxwmqv 7ce4029e remote @git (behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @git: zsuskuln 38a20473 (empty) description 2 [EOF] "); origin_dir.run_jj(["git", "export"]).success(); // Delete bookmark1 locally work_dir .run_jj(["bookmark", "delete", "bookmark1"]) .success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1 (deleted) @origin: qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); let output = work_dir.run_jj(["git", "push", "--bookmark", "bookmark1"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Delete bookmark bookmark1 from 9b2e76de3920 Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF] [exit status: 1] ");} #[test]fn test_git_push_unexpectedly_deleted() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Delete bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["bookmark", "delete", "bookmark1"]) .success(); insta::assert_snapshot!(get_bookmark_output(&origin_dir), @r" bookmark1 (deleted) @git: qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @git: zsuskuln 38a20473 (empty) description 2 [EOF] "); origin_dir.run_jj(["git", "export"]).success(); // Move bookmark1 sideways to another commit locally work_dir.run_jj(["new", "root()", "-m=local"]).success(); work_dir.write_file("local", "local"); work_dir .run_jj(["bookmark", "set", "bookmark1", "--allow-backwards", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: kpqxywon 09919fb0 local @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); // Pushing a moved bookmark fails if deleted on remote let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 09919fb051bf Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF]Lines 1–500 of 2263. 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::to_toml_value; use crate::common::CommandOutput; use crate::common::TestEnvironment; use crate::common::TestWorkDir; fn git_repo_dir_for_jj_repo(work_dir: &TestWorkDir<'_>) -> std::path::PathBuf { work_dir .root() .join(".jj") .join("repo") .join("store") .join("git") } fn set_up(test_env: &TestEnvironment) { test_env.run_jj_in(".", ["git", "init", "origin"]).success(); let origin_dir = test_env.work_dir("origin"); let origin_git_repo_path = git_repo_dir_for_jj_repo(&origin_dir); origin_dir .run_jj(["describe", "-m=description 1"]) .success(); origin_dir .run_jj(["bookmark", "create", "-r@", "bookmark1"]) .success(); origin_dir .run_jj(["new", "root()", "-m=description 2"]) .success(); origin_dir .run_jj(["bookmark", "create", "-r@", "bookmark2"]) .success(); origin_dir.run_jj(["git", "export"]).success(); test_env .run_jj_in( ".", [ "git", "clone", "--config=git.auto-local-bookmark=true", origin_git_repo_path.to_str().unwrap(), "local", ], ) .success(); } #[test] fn test_git_push_nothing() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Show the setup. `insta` has trouble if this is done inside `set_up()` insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: qpvuntsm 9b2e76de (empty) description 1 @origin: qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); // No bookmarks to push yet let output = work_dir.run_jj(["git", "push", "--all"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Nothing changed. [EOF] "); } #[test] fn test_git_push_current_bookmark() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); 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. work_dir .run_jj(["describe", "bookmark1", "-m", "modified bookmark1 commit"]) .success(); work_dir.run_jj(["new", "bookmark2"]).success(); work_dir .run_jj(["bookmark", "set", "bookmark2", "-r@"]) .success(); work_dir .run_jj(["bookmark", "create", "-r@", "my-bookmark"]) .success(); work_dir.run_jj(["describe", "-m", "foo"]).success(); // Check the setup insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: qpvuntsm e5ce6d9a (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 9b2e76de (empty) description 1 bookmark2: yostqsxw 88ca14a7 (empty) foo @origin (behind by 1 commits): zsuskuln 38a20473 (empty) description 2 my-bookmark: yostqsxw 88ca14a7 (empty) foo [EOF] "); // First dry-run. `bookmark1` should not get pushed. let output = work_dir.run_jj(["git", "push", "--allow-new", "--dry-run"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark2 from 38a204733702 to 88ca14a7d46f Add bookmark my-bookmark to 88ca14a7d46f Dry-run requested, not pushing. [EOF] "); let output = work_dir.run_jj(["git", "push", "--allow-new"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark2 from 38a204733702 to 88ca14a7d46f Add bookmark my-bookmark to 88ca14a7d46f [EOF] "); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: qpvuntsm e5ce6d9a (empty) modified bookmark1 commit @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm hidden 9b2e76de (empty) description 1 bookmark2: yostqsxw 88ca14a7 (empty) foo @origin: yostqsxw 88ca14a7 (empty) foo my-bookmark: yostqsxw 88ca14a7 (empty) foo @origin: yostqsxw 88ca14a7 (empty) foo [EOF] "); // Try pushing backwards work_dir .run_jj([ "bookmark", "set", "bookmark2", "-rbookmark2-", "--allow-backwards", ]) .success(); // This behavior is a strangeness of our definition of the default push revset. // We could consider changing it. let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] "); // We can move a bookmark backwards let output = work_dir.run_jj(["git", "push", "-bbookmark2"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move backward bookmark bookmark2 from 88ca14a7d46f to 38a204733702 [EOF] "); } #[test] fn test_git_push_parent_bookmark() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); test_env.add_config(r#"revset-aliases."immutable_heads()" = "none()""#); work_dir.run_jj(["edit", "bookmark1"]).success(); work_dir .run_jj(["describe", "-m", "modified bookmark1 commit"]) .success(); work_dir .run_jj(["new", "-m", "non-empty description"]) .success(); work_dir.write_file("file", "file"); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 80560a3e08e2 [EOF] "); } #[test] fn test_git_push_no_matching_bookmark() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); work_dir.run_jj(["new"]).success(); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] "); } #[test] fn test_git_push_matching_bookmark_unchanged() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); work_dir.run_jj(["new", "bookmark1"]).success(); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] "); } /// 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 = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); 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"); work_dir .run_jj([ "git", "remote", "add", "other", other_remote_path.to_str().unwrap(), ]) .success(); // Modify bookmark1 and push it to `origin` work_dir.run_jj(["edit", "bookmark1"]).success(); work_dir.run_jj(["describe", "-m=modified"]).success(); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to a843bfad2abb [EOF] "); // Since it's already pushed to origin, nothing will happen if push again let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Warning: No bookmarks found in the default push revset: remote_bookmarks(remote=origin)..@ Nothing changed. [EOF] "); // 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 output = work_dir.run_jj(["git", "push", "--allow-new", "--remote=other"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to other: Add bookmark bookmark1 to a843bfad2abb [EOF] "); } #[test] fn test_git_push_forward_unexpectedly_moved() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Move bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["new", "bookmark1", "-m=remote"]) .success(); origin_dir.write_file("remote", "remote"); origin_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); origin_dir.run_jj(["git", "export"]).success(); // Move bookmark1 forward to another commit locally work_dir.run_jj(["new", "bookmark1", "-m=local"]).success(); work_dir.write_file("local", "local"); work_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); // Pushing should fail let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark1 from 9b2e76de3920 to 624f94a35f00 Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF] [exit status: 1] "); // The ref name should be colorized let output = work_dir.run_jj(["git", "push", "--color=always"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move forward bookmark bookmark1 from 9b2e76de3920 to 624f94a35f00 [1m[38;5;1mError: [39mFailed to push some bookmarks[0m [1m[38;5;6mHint: [0m[39mThe following references unexpectedly moved on the remote:[39m [39m [38;5;2mrefs/heads/bookmark1[39m (reason: stale info)[39m [1m[38;5;6mHint: [0m[39mTry fetching from the remote, then make the bookmark point to where you want it to be, and push again.[39m [EOF] [exit status: 1] "); } #[test] fn test_git_push_sideways_unexpectedly_moved() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Move bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["new", "bookmark1", "-m=remote"]) .success(); origin_dir.write_file("remote", "remote"); origin_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&origin_dir), @r" bookmark1: vruxwmqv 7ce4029e remote @git (behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @git: zsuskuln 38a20473 (empty) description 2 [EOF] "); origin_dir.run_jj(["git", "export"]).success(); // Move bookmark1 sideways to another commit locally work_dir.run_jj(["new", "root()", "-m=local"]).success(); work_dir.write_file("local", "local"); work_dir .run_jj(["bookmark", "set", "bookmark1", "--allow-backwards", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: kmkuslsw 827b8a38 local @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 827b8a385853 Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF] [exit status: 1] "); // The ref name should be colorized let output = work_dir.run_jj(["git", "push", "--color=always"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 827b8a385853 [1m[38;5;1mError: [39mFailed to push some bookmarks[0m [1m[38;5;6mHint: [0m[39mThe following references unexpectedly moved on the remote:[39m [39m [38;5;2mrefs/heads/bookmark1[39m (reason: stale info)[39m [1m[38;5;6mHint: [0m[39mTry fetching from the remote, then make the bookmark point to where you want it to be, and push again.[39m [EOF] [exit status: 1] "); } // 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 = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Move bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["new", "bookmark1", "-m=remote"]) .success(); origin_dir.write_file("remote", "remote"); origin_dir .run_jj(["bookmark", "set", "bookmark1", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&origin_dir), @r" bookmark1: vruxwmqv 7ce4029e remote @git (behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @git: zsuskuln 38a20473 (empty) description 2 [EOF] "); origin_dir.run_jj(["git", "export"]).success(); // Delete bookmark1 locally work_dir .run_jj(["bookmark", "delete", "bookmark1"]) .success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1 (deleted) @origin: qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); let output = work_dir.run_jj(["git", "push", "--bookmark", "bookmark1"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Delete bookmark bookmark1 from 9b2e76de3920 Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF] [exit status: 1] "); } #[test] fn test_git_push_unexpectedly_deleted() { let test_env = TestEnvironment::default(); set_up(&test_env); let work_dir = test_env.work_dir("local"); // Delete bookmark1 forward on the remote let origin_dir = test_env.work_dir("origin"); origin_dir .run_jj(["bookmark", "delete", "bookmark1"]) .success(); insta::assert_snapshot!(get_bookmark_output(&origin_dir), @r" bookmark1 (deleted) @git: qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @git: zsuskuln 38a20473 (empty) description 2 [EOF] "); origin_dir.run_jj(["git", "export"]).success(); // Move bookmark1 sideways to another commit locally work_dir.run_jj(["new", "root()", "-m=local"]).success(); work_dir.write_file("local", "local"); work_dir .run_jj(["bookmark", "set", "bookmark1", "--allow-backwards", "-r@"]) .success(); insta::assert_snapshot!(get_bookmark_output(&work_dir), @r" bookmark1: kpqxywon 09919fb0 local @origin (ahead by 1 commits, behind by 1 commits): qpvuntsm 9b2e76de (empty) description 1 bookmark2: zsuskuln 38a20473 (empty) description 2 @origin: zsuskuln 38a20473 (empty) description 2 [EOF] "); // Pushing a moved bookmark fails if deleted on remote let output = work_dir.run_jj(["git", "push"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Changes to push to origin: Move sideways bookmark bookmark1 from 9b2e76de3920 to 09919fb051bf Error: Failed to push some bookmarks Hint: The following references unexpectedly moved on the remote: refs/heads/bookmark1 (reason: stale info) Hint: Try fetching from the remote, then make the bookmark point to where you want it to be, and push again. [EOF]