// 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 test_case::test_case; use crate::common::CommandOutput;use crate::common::TestEnvironment; /// Test adding a second workspace#[test]fn test_workspaces_add_second_workspace() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); let secondary_path = test_env.env_root().join("secondary"); std::fs::write(main_path.join("file"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "initial"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz 8183d0fc (empty) (no description set) [EOF] "); let output = test_env.run_jj_in( &main_path, ["workspace", "add", "--name", "second", "../secondary"], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Working copy (@) now at: rzvqmyuk 5ed2222c (empty) (no description set) Parent commit (@-) : qpvuntsm 751b12b7 initial Added 1 files, modified 0 files, removed 0 files [EOF] "#); // Can see the working-copy commit in each workspace in the log output. The "@" // node in the graph indicates the current workspace's working-copy commit. insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 8183d0fcaa4c default@ │ ○ 5ed2222c28e2 second@ ├─╯ ○ 751b12b7b981 ◆ 000000000000 [EOF] "); insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r" @ 5ed2222c28e2 second@ │ ○ 8183d0fcaa4c default@ ├─╯ ○ 751b12b7b981 ◆ 000000000000 [EOF] "); // Both workspaces show up when we list them let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz 8183d0fc (empty) (no description set) second: rzvqmyuk 5ed2222c (empty) (no description set) [EOF] ");} /// Test how sparse patterns are inherited#[test]fn test_workspaces_sparse_patterns() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "ws1"]).success(); let ws1_path = test_env.env_root().join("ws1"); let ws2_path = test_env.env_root().join("ws2"); let ws3_path = test_env.env_root().join("ws3"); let ws4_path = test_env.env_root().join("ws4"); let ws5_path = test_env.env_root().join("ws5"); let ws6_path = test_env.env_root().join("ws6"); test_env .run_jj_in(&ws1_path, ["sparse", "set", "--clear", "--add=foo"]) .success(); test_env .run_jj_in(&ws1_path, ["workspace", "add", "../ws2"]) .success(); let output = test_env.run_jj_in(&ws2_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" foo [EOF] "); test_env .run_jj_in(&ws2_path, ["sparse", "set", "--add=bar"]) .success(); test_env .run_jj_in(&ws2_path, ["workspace", "add", "../ws3"]) .success(); let output = test_env.run_jj_in(&ws3_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" bar foo [EOF] "); // --sparse-patterns behavior test_env .run_jj_in( &ws3_path, ["workspace", "add", "--sparse-patterns=copy", "../ws4"], ) .success(); let output = test_env.run_jj_in(&ws4_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" bar foo [EOF] "); test_env .run_jj_in( &ws3_path, ["workspace", "add", "--sparse-patterns=full", "../ws5"], ) .success(); let output = test_env.run_jj_in(&ws5_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" . [EOF] "); test_env .run_jj_in( &ws3_path, ["workspace", "add", "--sparse-patterns=empty", "../ws6"], ) .success(); let output = test_env.run_jj_in(&ws6_path, ["sparse", "list"]); insta::assert_snapshot!(output, @"");} /// Test adding a second workspace while the current workspace is editing a/// merge#[test]fn test_workspaces_add_second_workspace_on_merge() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); test_env .run_jj_in(&main_path, ["describe", "-m=left"]) .success(); test_env .run_jj_in(&main_path, ["new", "@-", "-m=right"]) .success(); test_env .run_jj_in(&main_path, ["new", "all:@-+", "-m=merge"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: zsuskuln 35e47bff (empty) merge [EOF] "); test_env .run_jj_in( &main_path, ["workspace", "add", "--name", "second", "../secondary"], ) .success(); // The new workspace's working-copy commit shares all parents with the old one. insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 35e47bff781e default@ ├─╮ │ │ ○ 7013a493bd09 second@ ╭─┬─╯ │ ○ 444b77e99d43 ○ │ 1694f2ddf8ec ├─╯ ◆ 000000000000 [EOF] ");} /// Test that --ignore-working-copy is respected#[test]fn test_workspaces_add_ignore_working_copy() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); // TODO: maybe better to error out early? let output = test_env.run_jj_in( &main_path, ["workspace", "add", "--ignore-working-copy", "../secondary"], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Error: This command must be able to update the working copy. Hint: Don't use --ignore-working-copy. [EOF] [exit status: 1] "#);} /// Test that --at-op is respected#[test]fn test_workspaces_add_at_operation() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); std::fs::write(main_path.join("file1"), "").unwrap(); let output = test_env.run_jj_in(&main_path, ["commit", "-m1"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Working copy (@) now at: rlvkpnrz 18d8b994 (empty) (no description set) Parent commit (@-) : qpvuntsm 3364a7ed 1 [EOF] "); std::fs::write(main_path.join("file2"), "").unwrap(); let output = test_env.run_jj_in(&main_path, ["commit", "-m2"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Working copy (@) now at: kkmpptxz 2e7dc5ab (empty) (no description set) Parent commit (@-) : rlvkpnrz 0dbaa19a 2 [EOF] "); // --at-op should disable snapshot in the main workspace, but the newly // created workspace should still be writable. std::fs::write(main_path.join("file3"), "").unwrap(); let output = test_env.run_jj_in( &main_path, ["workspace", "add", "--at-op=@-", "../secondary"], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Working copy (@) now at: rzvqmyuk a4d1cbc9 (empty) (no description set) Parent commit (@-) : qpvuntsm 3364a7ed 1 Added 1 files, modified 0 files, removed 0 files [EOF] "#); let secondary_path = test_env.env_root().join("secondary"); // New snapshot can be taken in the secondary workspace. std::fs::write(secondary_path.join("file4"), "").unwrap(); let output = test_env.run_jj_in(&secondary_path, ["status"]); insta::assert_snapshot!(output, @r" Working copy changes: A file4 Working copy (@) : rzvqmyuk 2ba74f85 (no description set) Parent commit (@-): qpvuntsm 3364a7ed 1 [EOF] ------- stderr ------- Concurrent modification detected, resolving automatically. [EOF] "); let output = test_env.run_jj_in(&secondary_path, ["op", "log", "-Tdescription"]); insta::assert_snapshot!(output, @r" @ snapshot working copy ○ reconcile divergent operations ├─╮ ○ │ commit cd06097124e3e5860867e35c2bb105902c28ea38 │ ○ create initial working-copy commit in workspace secondary │ ○ add workspace 'secondary' ├─╯ ○ snapshot working copy ○ commit 1c867a0762e30de4591890ea208849f793742c1b ○ snapshot working copy ○ add workspace 'default' ○ [EOF] ");} /// Test adding a workspace, but at a specific revision using '-r'#[test]fn test_workspaces_add_workspace_at_revision() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); let secondary_path = test_env.env_root().join("secondary"); std::fs::write(main_path.join("file-1"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "first"]) .success(); std::fs::write(main_path.join("file-2"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "second"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: kkmpptxz dadeedb4 (empty) (no description set) [EOF] "); let output = test_env.run_jj_in( &main_path, [ "workspace", "add", "--name", "second", "../secondary", "-r", "@--", ], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Working copy (@) now at: zxsnswpr e374e74a (empty) (no description set) Parent commit (@-) : qpvuntsm f6097c2f first Added 1 files, modified 0 files, removed 0 files [EOF] "#); // Can see the working-copy commit in each workspace in the log output. The "@" // node in the graph indicates the current workspace's working-copy commit. insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ dadeedb493e8 default@ ○ c420244c6398 │ ○ e374e74aa0c8 second@ ├─╯ ○ f6097c2f7cac ◆ 000000000000 [EOF] "); insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r" @ e374e74aa0c8 second@ │ ○ dadeedb493e8 default@ │ ○ c420244c6398 ├─╯ ○ f6097c2f7cac ◆ 000000000000 [EOF] ");} /// Test multiple `-r` flags to `workspace add` to create a workspace/// working-copy commit with multiple parents.#[test]fn test_workspaces_add_workspace_multiple_revisions() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); std::fs::write(main_path.join("file-1"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "first"]) .success(); test_env .run_jj_in(&main_path, ["new", "-r", "root()"]) .success(); std::fs::write(main_path.join("file-2"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "second"]) .success(); test_env .run_jj_in(&main_path, ["new", "-r", "root()"]) .success(); std::fs::write(main_path.join("file-3"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "third"]) .success(); test_env .run_jj_in(&main_path, ["new", "-r", "root()"]) .success(); insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 5b36783cd11c │ ○ 6c843d62ca29 ├─╯ │ ○ 544cd61f2d26 ├─╯ │ ○ f6097c2f7cac ├─╯ ◆ 000000000000 [EOF] "); let output = test_env.run_jj_in( &main_path, [ "workspace", "add", "--name=merge", "../merged", "-r=description(third)", "-r=description(second)", "-r=description(first)", ], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../merged" Working copy (@) now at: wmwvqwsz f4fa64f4 (empty) (no description set) Parent commit (@-) : mzvwutvl 6c843d62 third Parent commit (@-) : kkmpptxz 544cd61f second Parent commit (@-) : qpvuntsm f6097c2f first Added 3 files, modified 0 files, removed 0 files [EOF] "#); insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 5b36783cd11c default@ │ ○ f4fa64f40944 merge@ │ ├─┬─╮ │ │ │ ○ f6097c2f7cac ├─────╯ │ │ ○ 544cd61f2d26 ├───╯ │ ○ 6c843d62ca29 ├─╯ ◆ 000000000000 [EOF] ");} #[test]fn test_workspaces_add_workspace_from_subdir() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); let subdir_path = main_path.join("subdir"); let secondary_path = test_env.env_root().join("secondary"); std::fs::create_dir(&subdir_path).unwrap(); std::fs::write(subdir_path.join("file"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "initial"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz e1038e77 (empty) (no description set) [EOF] "); // Create workspace while in sub-directory of current workspace let output = test_env.run_jj_in(&subdir_path, ["workspace", "add", "../../secondary"]); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../../secondary" Working copy (@) now at: rzvqmyuk 7ad84461 (empty) (no description set) Parent commit (@-) : qpvuntsm a3a43d9e initial Added 1 files, modified 0 files, removed 0 files [EOF] "#); // Both workspaces show up when we list them let output = test_env.run_jj_in(&secondary_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz e1038e77 (empty) (no description set) secondary: rzvqmyuk 7ad84461 (empty) (no description set) [EOF] ");} #[test]fn test_workspaces_add_workspace_in_current_workspace() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); std::fs::write(main_path.join("file"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "initial"]) .success(); // Try to create workspace using name instead of path let output = test_env.run_jj_in(&main_path, ["workspace", "add", "secondary"]); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "secondary" Warning: Workspace created inside current directory. If this was unintentional, delete the "secondary" directory and run `jj workspace forget secondary` to remove it. Working copy (@) now at: pmmvwywv 0a77a39d (empty) (no description set) Parent commit (@-) : qpvuntsm 751b12b7 initial Added 1 files, modified 0 files, removed 0 filesLines 1–500 of 1490. 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 test_case::test_case; use crate::common::CommandOutput; use crate::common::TestEnvironment; /// Test adding a second workspace #[test] fn test_workspaces_add_second_workspace() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); let secondary_path = test_env.env_root().join("secondary"); std::fs::write(main_path.join("file"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "initial"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz 8183d0fc (empty) (no description set) [EOF] "); let output = test_env.run_jj_in( &main_path, ["workspace", "add", "--name", "second", "../secondary"], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Working copy (@) now at: rzvqmyuk 5ed2222c (empty) (no description set) Parent commit (@-) : qpvuntsm 751b12b7 initial Added 1 files, modified 0 files, removed 0 files [EOF] "#); // Can see the working-copy commit in each workspace in the log output. The "@" // node in the graph indicates the current workspace's working-copy commit. insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 8183d0fcaa4c default@ │ ○ 5ed2222c28e2 second@ ├─╯ ○ 751b12b7b981 ◆ 000000000000 [EOF] "); insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r" @ 5ed2222c28e2 second@ │ ○ 8183d0fcaa4c default@ ├─╯ ○ 751b12b7b981 ◆ 000000000000 [EOF] "); // Both workspaces show up when we list them let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz 8183d0fc (empty) (no description set) second: rzvqmyuk 5ed2222c (empty) (no description set) [EOF] "); } /// Test how sparse patterns are inherited #[test] fn test_workspaces_sparse_patterns() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "ws1"]).success(); let ws1_path = test_env.env_root().join("ws1"); let ws2_path = test_env.env_root().join("ws2"); let ws3_path = test_env.env_root().join("ws3"); let ws4_path = test_env.env_root().join("ws4"); let ws5_path = test_env.env_root().join("ws5"); let ws6_path = test_env.env_root().join("ws6"); test_env .run_jj_in(&ws1_path, ["sparse", "set", "--clear", "--add=foo"]) .success(); test_env .run_jj_in(&ws1_path, ["workspace", "add", "../ws2"]) .success(); let output = test_env.run_jj_in(&ws2_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" foo [EOF] "); test_env .run_jj_in(&ws2_path, ["sparse", "set", "--add=bar"]) .success(); test_env .run_jj_in(&ws2_path, ["workspace", "add", "../ws3"]) .success(); let output = test_env.run_jj_in(&ws3_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" bar foo [EOF] "); // --sparse-patterns behavior test_env .run_jj_in( &ws3_path, ["workspace", "add", "--sparse-patterns=copy", "../ws4"], ) .success(); let output = test_env.run_jj_in(&ws4_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" bar foo [EOF] "); test_env .run_jj_in( &ws3_path, ["workspace", "add", "--sparse-patterns=full", "../ws5"], ) .success(); let output = test_env.run_jj_in(&ws5_path, ["sparse", "list"]); insta::assert_snapshot!(output, @r" . [EOF] "); test_env .run_jj_in( &ws3_path, ["workspace", "add", "--sparse-patterns=empty", "../ws6"], ) .success(); let output = test_env.run_jj_in(&ws6_path, ["sparse", "list"]); insta::assert_snapshot!(output, @""); } /// Test adding a second workspace while the current workspace is editing a /// merge #[test] fn test_workspaces_add_second_workspace_on_merge() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); test_env .run_jj_in(&main_path, ["describe", "-m=left"]) .success(); test_env .run_jj_in(&main_path, ["new", "@-", "-m=right"]) .success(); test_env .run_jj_in(&main_path, ["new", "all:@-+", "-m=merge"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: zsuskuln 35e47bff (empty) merge [EOF] "); test_env .run_jj_in( &main_path, ["workspace", "add", "--name", "second", "../secondary"], ) .success(); // The new workspace's working-copy commit shares all parents with the old one. insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 35e47bff781e default@ ├─╮ │ │ ○ 7013a493bd09 second@ ╭─┬─╯ │ ○ 444b77e99d43 ○ │ 1694f2ddf8ec ├─╯ ◆ 000000000000 [EOF] "); } /// Test that --ignore-working-copy is respected #[test] fn test_workspaces_add_ignore_working_copy() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); // TODO: maybe better to error out early? let output = test_env.run_jj_in( &main_path, ["workspace", "add", "--ignore-working-copy", "../secondary"], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Error: This command must be able to update the working copy. Hint: Don't use --ignore-working-copy. [EOF] [exit status: 1] "#); } /// Test that --at-op is respected #[test] fn test_workspaces_add_at_operation() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); std::fs::write(main_path.join("file1"), "").unwrap(); let output = test_env.run_jj_in(&main_path, ["commit", "-m1"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Working copy (@) now at: rlvkpnrz 18d8b994 (empty) (no description set) Parent commit (@-) : qpvuntsm 3364a7ed 1 [EOF] "); std::fs::write(main_path.join("file2"), "").unwrap(); let output = test_env.run_jj_in(&main_path, ["commit", "-m2"]); insta::assert_snapshot!(output, @r" ------- stderr ------- Working copy (@) now at: kkmpptxz 2e7dc5ab (empty) (no description set) Parent commit (@-) : rlvkpnrz 0dbaa19a 2 [EOF] "); // --at-op should disable snapshot in the main workspace, but the newly // created workspace should still be writable. std::fs::write(main_path.join("file3"), "").unwrap(); let output = test_env.run_jj_in( &main_path, ["workspace", "add", "--at-op=@-", "../secondary"], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Working copy (@) now at: rzvqmyuk a4d1cbc9 (empty) (no description set) Parent commit (@-) : qpvuntsm 3364a7ed 1 Added 1 files, modified 0 files, removed 0 files [EOF] "#); let secondary_path = test_env.env_root().join("secondary"); // New snapshot can be taken in the secondary workspace. std::fs::write(secondary_path.join("file4"), "").unwrap(); let output = test_env.run_jj_in(&secondary_path, ["status"]); insta::assert_snapshot!(output, @r" Working copy changes: A file4 Working copy (@) : rzvqmyuk 2ba74f85 (no description set) Parent commit (@-): qpvuntsm 3364a7ed 1 [EOF] ------- stderr ------- Concurrent modification detected, resolving automatically. [EOF] "); let output = test_env.run_jj_in(&secondary_path, ["op", "log", "-Tdescription"]); insta::assert_snapshot!(output, @r" @ snapshot working copy ○ reconcile divergent operations ├─╮ ○ │ commit cd06097124e3e5860867e35c2bb105902c28ea38 │ ○ create initial working-copy commit in workspace secondary │ ○ add workspace 'secondary' ├─╯ ○ snapshot working copy ○ commit 1c867a0762e30de4591890ea208849f793742c1b ○ snapshot working copy ○ add workspace 'default' ○ [EOF] "); } /// Test adding a workspace, but at a specific revision using '-r' #[test] fn test_workspaces_add_workspace_at_revision() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); let secondary_path = test_env.env_root().join("secondary"); std::fs::write(main_path.join("file-1"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "first"]) .success(); std::fs::write(main_path.join("file-2"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "second"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: kkmpptxz dadeedb4 (empty) (no description set) [EOF] "); let output = test_env.run_jj_in( &main_path, [ "workspace", "add", "--name", "second", "../secondary", "-r", "@--", ], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../secondary" Working copy (@) now at: zxsnswpr e374e74a (empty) (no description set) Parent commit (@-) : qpvuntsm f6097c2f first Added 1 files, modified 0 files, removed 0 files [EOF] "#); // Can see the working-copy commit in each workspace in the log output. The "@" // node in the graph indicates the current workspace's working-copy commit. insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ dadeedb493e8 default@ ○ c420244c6398 │ ○ e374e74aa0c8 second@ ├─╯ ○ f6097c2f7cac ◆ 000000000000 [EOF] "); insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r" @ e374e74aa0c8 second@ │ ○ dadeedb493e8 default@ │ ○ c420244c6398 ├─╯ ○ f6097c2f7cac ◆ 000000000000 [EOF] "); } /// Test multiple `-r` flags to `workspace add` to create a workspace /// working-copy commit with multiple parents. #[test] fn test_workspaces_add_workspace_multiple_revisions() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); std::fs::write(main_path.join("file-1"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "first"]) .success(); test_env .run_jj_in(&main_path, ["new", "-r", "root()"]) .success(); std::fs::write(main_path.join("file-2"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "second"]) .success(); test_env .run_jj_in(&main_path, ["new", "-r", "root()"]) .success(); std::fs::write(main_path.join("file-3"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "third"]) .success(); test_env .run_jj_in(&main_path, ["new", "-r", "root()"]) .success(); insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 5b36783cd11c │ ○ 6c843d62ca29 ├─╯ │ ○ 544cd61f2d26 ├─╯ │ ○ f6097c2f7cac ├─╯ ◆ 000000000000 [EOF] "); let output = test_env.run_jj_in( &main_path, [ "workspace", "add", "--name=merge", "../merged", "-r=description(third)", "-r=description(second)", "-r=description(first)", ], ); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../merged" Working copy (@) now at: wmwvqwsz f4fa64f4 (empty) (no description set) Parent commit (@-) : mzvwutvl 6c843d62 third Parent commit (@-) : kkmpptxz 544cd61f second Parent commit (@-) : qpvuntsm f6097c2f first Added 3 files, modified 0 files, removed 0 files [EOF] "#); insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r" @ 5b36783cd11c default@ │ ○ f4fa64f40944 merge@ │ ├─┬─╮ │ │ │ ○ f6097c2f7cac ├─────╯ │ │ ○ 544cd61f2d26 ├───╯ │ ○ 6c843d62ca29 ├─╯ ◆ 000000000000 [EOF] "); } #[test] fn test_workspaces_add_workspace_from_subdir() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); let subdir_path = main_path.join("subdir"); let secondary_path = test_env.env_root().join("secondary"); std::fs::create_dir(&subdir_path).unwrap(); std::fs::write(subdir_path.join("file"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "initial"]) .success(); let output = test_env.run_jj_in(&main_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz e1038e77 (empty) (no description set) [EOF] "); // Create workspace while in sub-directory of current workspace let output = test_env.run_jj_in(&subdir_path, ["workspace", "add", "../../secondary"]); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "../../secondary" Working copy (@) now at: rzvqmyuk 7ad84461 (empty) (no description set) Parent commit (@-) : qpvuntsm a3a43d9e initial Added 1 files, modified 0 files, removed 0 files [EOF] "#); // Both workspaces show up when we list them let output = test_env.run_jj_in(&secondary_path, ["workspace", "list"]); insta::assert_snapshot!(output, @r" default: rlvkpnrz e1038e77 (empty) (no description set) secondary: rzvqmyuk 7ad84461 (empty) (no description set) [EOF] "); } #[test] fn test_workspaces_add_workspace_in_current_workspace() { let test_env = TestEnvironment::default(); test_env.run_jj_in(".", ["git", "init", "main"]).success(); let main_path = test_env.env_root().join("main"); std::fs::write(main_path.join("file"), "contents").unwrap(); test_env .run_jj_in(&main_path, ["commit", "-m", "initial"]) .success(); // Try to create workspace using name instead of path let output = test_env.run_jj_in(&main_path, ["workspace", "add", "secondary"]); insta::assert_snapshot!(output.normalize_backslash(), @r#" ------- stderr ------- Created workspace in "secondary" Warning: Workspace created inside current directory. If this was unintentional, delete the "secondary" directory and run `jj workspace forget secondary` to remove it. Working copy (@) now at: pmmvwywv 0a77a39d (empty) (no description set) Parent commit (@-) : qpvuntsm 751b12b7 initial Added 1 files, modified 0 files, removed 0 files