1170 lines · 44.9 KB · Rust
RawDownload
// 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 crate::common::TestEnvironment; /// Test adding a second workspace#[test]fn test_workspaces_add_second_workspace() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    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.jj_cmd_ok(&main_path, &["commit", "-m", "initial"]);     let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: rlvkpnrz 8183d0fc (empty) (no description set)    "###);     let (stdout, stderr) = test_env.jj_cmd_ok(        &main_path,        &["workspace", "add", "--name", "second", "../secondary"],    );    insta::assert_snapshot!(stdout.replace('\\', "/"), @"");    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    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    "###);     // 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###"    ○  5ed2222c28e2 second@    │ @  8183d0fcaa4c default@    ├─╯    ○  751b12b7b981    ◆  000000000000    "###);    insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r###"    @  5ed2222c28e2 second@    │ ○  8183d0fcaa4c default@    ├─╯    ○  751b12b7b981    ◆  000000000000    "###);     // Both workspaces show up when we list them    let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: rlvkpnrz 8183d0fc (empty) (no description set)    second: rzvqmyuk 5ed2222c (empty) (no description set)    "###);} /// Test how sparse patterns are inherited#[test]fn test_workspaces_sparse_patterns() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "ws1"]);    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.jj_cmd_ok(&ws1_path, &["sparse", "set", "--clear", "--add=foo"]);    test_env.jj_cmd_ok(&ws1_path, &["workspace", "add", "../ws2"]);    let stdout = test_env.jj_cmd_success(&ws2_path, &["sparse", "list"]);    insta::assert_snapshot!(stdout, @r###"    foo    "###);    test_env.jj_cmd_ok(&ws2_path, &["sparse", "set", "--add=bar"]);    test_env.jj_cmd_ok(&ws2_path, &["workspace", "add", "../ws3"]);    let stdout = test_env.jj_cmd_success(&ws3_path, &["sparse", "list"]);    insta::assert_snapshot!(stdout, @r###"    bar    foo    "###);    // --sparse-patterns behavior    test_env.jj_cmd_ok(        &ws3_path,        &["workspace", "add", "--sparse-patterns=copy", "../ws4"],    );    let stdout = test_env.jj_cmd_success(&ws4_path, &["sparse", "list"]);    insta::assert_snapshot!(stdout, @r###"    bar    foo    "###);    test_env.jj_cmd_ok(        &ws3_path,        &["workspace", "add", "--sparse-patterns=full", "../ws5"],    );    let stdout = test_env.jj_cmd_success(&ws5_path, &["sparse", "list"]);    insta::assert_snapshot!(stdout, @r###"    .    "###);    test_env.jj_cmd_ok(        &ws3_path,        &["workspace", "add", "--sparse-patterns=empty", "../ws6"],    );    let stdout = test_env.jj_cmd_success(&ws6_path, &["sparse", "list"]);    insta::assert_snapshot!(stdout, @"");} /// 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.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    let main_path = test_env.env_root().join("main");     test_env.jj_cmd_ok(&main_path, &["describe", "-m=left"]);    test_env.jj_cmd_ok(&main_path, &["new", "@-", "-m=right"]);    test_env.jj_cmd_ok(&main_path, &["new", "all:@-+", "-m=merge"]);     let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: zsuskuln 35e47bff (empty) merge    "###);     test_env.jj_cmd_ok(        &main_path,        &["workspace", "add", "--name", "second", "../secondary"],    );     // 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###"    ○    7013a493bd09 second@    ├─╮    │ │ @  35e47bff781e default@    ╭─┬─╯    │ ○  444b77e99d43    ○ │  1694f2ddf8ec    ├─╯    ◆  000000000000    "###);} /// Test that --ignore-working-copy is respected#[test]fn test_workspaces_add_ignore_working_copy() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    let main_path = test_env.env_root().join("main");     // TODO: maybe better to error out early?    let stderr = test_env.jj_cmd_failure(        &main_path,        &["workspace", "add", "--ignore-working-copy", "../secondary"],    );    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    Created workspace in "../secondary"    Error: This command must be able to update the working copy.    Hint: Don't use --ignore-working-copy.    "###);} /// Test that --at-op is respected#[test]fn test_workspaces_add_at_operation() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    let main_path = test_env.env_root().join("main");     std::fs::write(main_path.join("file1"), "").unwrap();    let (_stdout, stderr) = test_env.jj_cmd_ok(&main_path, &["commit", "-m1"]);    insta::assert_snapshot!(stderr, @r###"    Working copy now at: rlvkpnrz 18d8b994 (empty) (no description set)    Parent commit      : qpvuntsm 3364a7ed 1    "###);     std::fs::write(main_path.join("file2"), "").unwrap();    let (_stdout, stderr) = test_env.jj_cmd_ok(&main_path, &["commit", "-m2"]);    insta::assert_snapshot!(stderr, @r###"    Working copy now at: kkmpptxz 2e7dc5ab (empty) (no description set)    Parent commit      : rlvkpnrz 0dbaa19a 2    "###);     // --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 (_stdout, stderr) = test_env.jj_cmd_ok(        &main_path,        &["workspace", "add", "--at-op=@-", "../secondary"],    );    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    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    "###);    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 (stdout, stderr) = test_env.jj_cmd_ok(&secondary_path, &["status"]);    insta::assert_snapshot!(stdout, @r###"    Working copy changes:    A file4    Working copy : rzvqmyuk 2ba74f85 (no description set)    Parent commit: qpvuntsm 3364a7ed 1    "###);    insta::assert_snapshot!(stderr, @r###"    Concurrent modification detected, resolving automatically.    "###);     let stdout = test_env.jj_cmd_success(&secondary_path, &["op", "log", "-Tdescription"]);    insta::assert_snapshot!(stdout, @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'    ○    "#);} /// 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.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    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.jj_cmd_ok(&main_path, &["commit", "-m", "first"]);     std::fs::write(main_path.join("file-2"), "contents").unwrap();    test_env.jj_cmd_ok(&main_path, &["commit", "-m", "second"]);     let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: kkmpptxz dadeedb4 (empty) (no description set)    "###);     let (_, stderr) = test_env.jj_cmd_ok(        &main_path,        &[            "workspace",            "add",            "--name",            "second",            "../secondary",            "-r",            "@--",        ],    );    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    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    "###);     // 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###"    ○  e374e74aa0c8 second@    │ @  dadeedb493e8 default@    │ ○  c420244c6398    ├─╯    ○  f6097c2f7cac    ◆  000000000000    "###);    insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r###"    @  e374e74aa0c8 second@    │ ○  dadeedb493e8 default@    │ ○  c420244c6398    ├─╯    ○  f6097c2f7cac    ◆  000000000000    "###);} /// 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.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    let main_path = test_env.env_root().join("main");     std::fs::write(main_path.join("file-1"), "contents").unwrap();    test_env.jj_cmd_ok(&main_path, &["commit", "-m", "first"]);    test_env.jj_cmd_ok(&main_path, &["new", "-r", "root()"]);     std::fs::write(main_path.join("file-2"), "contents").unwrap();    test_env.jj_cmd_ok(&main_path, &["commit", "-m", "second"]);    test_env.jj_cmd_ok(&main_path, &["new", "-r", "root()"]);     std::fs::write(main_path.join("file-3"), "contents").unwrap();    test_env.jj_cmd_ok(&main_path, &["commit", "-m", "third"]);    test_env.jj_cmd_ok(&main_path, &["new", "-r", "root()"]);     insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    @  5b36783cd11c    │ ○  6c843d62ca29    ├─╯    │ ○  544cd61f2d26    ├─╯    │ ○  f6097c2f7cac    ├─╯    ◆  000000000000    "###);     let (_, stderr) = test_env.jj_cmd_ok(        &main_path,        &[            "workspace",            "add",            "--name=merge",            "../merged",            "-r=description(third)",            "-r=description(second)",            "-r=description(first)",        ],    );    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    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    "###);     insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    ○      f4fa64f40944 merge@    ├─┬─╮    │ │ ○  f6097c2f7cac    │ ○ │  544cd61f2d26    │ ├─╯    ○ │  6c843d62ca29    ├─╯    │ @  5b36783cd11c default@    ├─╯    ◆  000000000000    "###);} #[test]fn test_workspaces_add_workspace_from_subdir() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    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.jj_cmd_ok(&main_path, &["commit", "-m", "initial"]);     let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: rlvkpnrz e1038e77 (empty) (no description set)    "###);     // Create workspace while in sub-directory of current workspace    let (stdout, stderr) =        test_env.jj_cmd_ok(&subdir_path, &["workspace", "add", "../../secondary"]);    insta::assert_snapshot!(stdout.replace('\\', "/"), @"");    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    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    "###);     // Both workspaces show up when we list them    let stdout = test_env.jj_cmd_success(&secondary_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: rlvkpnrz e1038e77 (empty) (no description set)    secondary: rzvqmyuk 7ad84461 (empty) (no description set)    "###);} #[test]fn test_workspaces_add_workspace_in_current_workspace() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    let main_path = test_env.env_root().join("main");     std::fs::write(main_path.join("file"), "contents").unwrap();    test_env.jj_cmd_ok(&main_path, &["commit", "-m", "initial"]);     // Try to create workspace using name instead of path    let (stdout, stderr) = test_env.jj_cmd_ok(&main_path, &["workspace", "add", "secondary"]);    insta::assert_snapshot!(stdout.replace('\\', "/"), @"");    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    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    "###);     // Workspace created despite warning    let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: rlvkpnrz 46d9ba8b (no description set)    secondary: pmmvwywv 0a77a39d (empty) (no description set)    "###);     // Use explicit path instead (no warning)    let (stdout, stderr) = test_env.jj_cmd_ok(&main_path, &["workspace", "add", "./third"]);    insta::assert_snapshot!(stdout.replace('\\', "/"), @"");    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    Created workspace in "third"    Working copy now at: zxsnswpr 64746d4b (empty) (no description set)    Parent commit      : qpvuntsm 751b12b7 initial    Added 1 files, modified 0 files, removed 0 files    "###);     // Both workspaces created    let stdout = test_env.jj_cmd_success(&main_path, &["workspace", "list"]);    insta::assert_snapshot!(stdout, @r###"    default: rlvkpnrz 477c647f (no description set)    secondary: pmmvwywv 0a77a39d (empty) (no description set)    third: zxsnswpr 64746d4b (empty) (no description set)    "###);     // Can see files from the other workspaces in main workspace, since they are    // child directories and will therefore be snapshotted    let stdout = test_env.jj_cmd_success(&main_path, &["file", "list"]);    insta::assert_snapshot!(stdout.replace('\\', "/"), @r###"    file    secondary/file    third/file    "###);} /// Test making changes to the working copy in a workspace as it gets rewritten/// from another workspace#[test]fn test_workspaces_conflicting_edits() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "main"]);    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\n").unwrap();    test_env.jj_cmd_ok(&main_path, &["new"]);     test_env.jj_cmd_ok(&main_path, &["workspace", "add", "../secondary"]);     insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    ○  3224de8ae048 secondary@    │ @  06b57f44a3ca default@    ├─╯    ○  506f4ec3c2c6    ◆  000000000000    "###);     // Make changes in both working copies    std::fs::write(main_path.join("file"), "changed in main\n").unwrap();    std::fs::write(secondary_path.join("file"), "changed in second\n").unwrap();    // Squash the changes from the main workspace into the initial commit (before    // running any command in the secondary workspace    let (stdout, stderr) = test_env.jj_cmd_ok(&main_path, &["squash"]);    insta::assert_snapshot!(stdout, @"");    insta::assert_snapshot!(stderr, @r###"    Rebased 1 descendant commits    Working copy now at: mzvwutvl a58c9a9b (empty) (no description set)    Parent commit      : qpvuntsm d4124476 (no description set)    "###);     // The secondary workspace's working-copy commit was updated    insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    @  a58c9a9b19ce default@    │ ○  e82cd4ee8faa secondary@    ├─╯    ○  d41244767d45    ◆  000000000000    "###);

Lines 1–500 of 1170.