757 lines · 31.2 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(), &["init", "--git", "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 e0e6d567 (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 397eac93 (empty) (no description set)    Parent commit      : qpvuntsm 7d308bc9 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###"    ◉  397eac932ad3c349b2659fd2eb035a4dd3da4193 second@    │ @  e0e6d5672858dc9a57ec5b772b7c4f3270ed0223 default@    ├─╯    ◉  7d308bc9d934c53c6cc52935192e2d6ac5d78cfd    ◉  0000000000000000000000000000000000000000    "###);    insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r###"    @  397eac932ad3c349b2659fd2eb035a4dd3da4193 second@    │ ◉  e0e6d5672858dc9a57ec5b772b7c4f3270ed0223 default@    ├─╯    ◉  7d308bc9d934c53c6cc52935192e2d6ac5d78cfd    ◉  0000000000000000000000000000000000000000    "###);     // 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 e0e6d567 (empty) (no description set)    second: rzvqmyuk 397eac93 (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(), &["init", "--git", "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");     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    "###);} /// 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(), &["init", "--git", "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 21a0ea6d (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###"    ◉    6d4c2b8ab610148410b6a346d900cb7ad6298ede second@    ├─╮    │ │ @  21a0ea6d1c86c413cb30d7f7d216a74754b148c4 default@    ╭─┬─╯    │ ◉  09ba8d9dfa21b8572c2361e6947ca024d8f0a198    ◉ │  1694f2ddf8ecf9e55ca3cd9554bc0654186b07e0    ├─╯    ◉  0000000000000000000000000000000000000000    "###);} /// 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(), &["init", "--git", "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 2801c219 (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 e6baf9d9 (empty) (no description set)    Parent commit      : qpvuntsm e7d7dbb9 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###"    ◉  e6baf9d9cfd0b616eac110fc5826b7eca63cffc5 second@    │ @  2801c219094d5d49a2c5697ba1c34b9593d2c2a9 default@    │ ◉  4ec5df5a189c813f8cc66aeb35e007929ebb46bc    ├─╯    ◉  e7d7dbb91c5a543ea680711093e689916d5f31df    ◉  0000000000000000000000000000000000000000    "###);    insta::assert_snapshot!(get_log_output(&test_env, &secondary_path), @r###"    @  e6baf9d9cfd0b616eac110fc5826b7eca63cffc5 second@    │ ◉  2801c219094d5d49a2c5697ba1c34b9593d2c2a9 default@    │ ◉  4ec5df5a189c813f8cc66aeb35e007929ebb46bc    ├─╯    ◉  e7d7dbb91c5a543ea680711093e689916d5f31df    ◉  0000000000000000000000000000000000000000    "###);} /// 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(), &["init", "--git", "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###"    @  5b36783cd11c4607a329c5e8c2fd9097c9ce2add    │ ◉  23881f07b53ce1ea936ca8842e344dea9c3356e5    ├─╯    │ ◉  1f6a15f0af2a985703864347f5fdf27a82fc3d73    ├─╯    │ ◉  e7d7dbb91c5a543ea680711093e689916d5f31df    ├─╯    ◉  0000000000000000000000000000000000000000    "###);     let (_, stderr) = test_env.jj_cmd_ok(        &main_path,        &[            "workspace",            "add",            "--name=merge",            "../merged",            "-r=238",            "-r=1f6",            "-r=e7d",        ],    );    insta::assert_snapshot!(stderr.replace('\\', "/"), @r###"    Created workspace in "../merged"    Working copy now at: wmwvqwsz fa8fdc28 (empty) (no description set)    Parent commit      : mzvwutvl 23881f07 third    Parent commit      : kkmpptxz 1f6a15f0 second    Parent commit      : qpvuntsm e7d7dbb9 first    Added 3 files, modified 0 files, removed 0 files    "###);     insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    ◉      fa8fdc28af12d3c96b1e0ed062f5a8f9a99818f0 merge@    ├─┬─╮    │ │ ◉  e7d7dbb91c5a543ea680711093e689916d5f31df    │ ◉ │  1f6a15f0af2a985703864347f5fdf27a82fc3d73    │ ├─╯    ◉ │  23881f07b53ce1ea936ca8842e344dea9c3356e5    ├─╯    │ @  5b36783cd11c4607a329c5e8c2fd9097c9ce2add default@    ├─╯    ◉  0000000000000000000000000000000000000000    "###);} /// 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(), &["init", "--git", "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###"    ◉  265af0cdbcc7bb33e3734ad72565c943ce3fb0d4 secondary@    │ @  351099fa72cfbb1b34e410e89821efc623295974 default@    ├─╯    ◉  cf911c223d3e24e001fc8264d6dbf0610804fc40    ◉  0000000000000000000000000000000000000000    "###);     // 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 fe8f41ed (empty) (no description set)    Parent commit      : qpvuntsm c0d4a99e (no description set)    "###);     // The secondary workspace's working-copy commit was updated    insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    @  fe8f41ed01d693b2d4365cd89e42ad9c531a939b default@    │ ◉  a1896a17282f19089a5cec44358d6609910e0513 secondary@    ├─╯    ◉  c0d4a99ef98ada7da8dc73a778bbb747c4178385    ◉  0000000000000000000000000000000000000000    "###);    let stderr = test_env.jj_cmd_failure(&secondary_path, &["st"]);    insta::assert_snapshot!(stderr, @r###"    Error: The working copy is stale (not updated since operation 58b580b12eee).    Hint: Run `jj workspace update-stale` to update it.    See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-working-copy for more information.    "###);    // Same error on second run, and from another command    let stderr = test_env.jj_cmd_failure(&secondary_path, &["log"]);    insta::assert_snapshot!(stderr, @r###"    Error: The working copy is stale (not updated since operation 58b580b12eee).    Hint: Run `jj workspace update-stale` to update it.    See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-working-copy for more information.    "###);    let (stdout, stderr) = test_env.jj_cmd_ok(&secondary_path, &["workspace", "update-stale"]);    // It was detected that the working copy is now stale.    // Since there was an uncommitted change in the working copy, it should    // have been committed first (causing divergence)    insta::assert_snapshot!(stdout, @"");    insta::assert_snapshot!(stderr, @r###"    Concurrent modification detected, resolving automatically.    Rebased 1 descendant commits onto commits rewritten by other operation    Working copy now at: pmmvwywv?? a1896a17 (empty) (no description set)    Added 0 files, modified 1 files, removed 0 files    "###);    insta::assert_snapshot!(get_log_output(&test_env, &secondary_path),    @r###"    ◉  a3c96849ef9f124cbfc2416dc13bf17309d5020a (divergent)    │ ◉  fe8f41ed01d693b2d4365cd89e42ad9c531a939b default@    ├─╯    │ @  a1896a17282f19089a5cec44358d6609910e0513 secondary@ (divergent)    ├─╯    ◉  c0d4a99ef98ada7da8dc73a778bbb747c4178385    ◉  0000000000000000000000000000000000000000    "###);    // The stale working copy should have been resolved by the previous command    let stdout = get_log_output(&test_env, &secondary_path);    assert!(!stdout.starts_with("The working copy is stale"));    insta::assert_snapshot!(stdout, @r###"    ◉  a3c96849ef9f124cbfc2416dc13bf17309d5020a (divergent)    │ ◉  fe8f41ed01d693b2d4365cd89e42ad9c531a939b default@    ├─╯    │ @  a1896a17282f19089a5cec44358d6609910e0513 secondary@ (divergent)    ├─╯    ◉  c0d4a99ef98ada7da8dc73a778bbb747c4178385    ◉  0000000000000000000000000000000000000000    "###);} /// Test a clean working copy that gets rewritten from another workspace#[test]fn test_workspaces_updated_by_other() {    let test_env = TestEnvironment::default();    test_env.jj_cmd_ok(test_env.env_root(), &["init", "--git", "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###"    ◉  265af0cdbcc7bb33e3734ad72565c943ce3fb0d4 secondary@    │ @  351099fa72cfbb1b34e410e89821efc623295974 default@    ├─╯    ◉  cf911c223d3e24e001fc8264d6dbf0610804fc40    ◉  0000000000000000000000000000000000000000    "###);     // Rewrite the check-out commit in one workspace.    std::fs::write(main_path.join("file"), "changed in main\n").unwrap();    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 fe8f41ed (empty) (no description set)    Parent commit      : qpvuntsm c0d4a99e (no description set)    "###);     // The secondary workspace's working-copy commit was updated.    insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    @  fe8f41ed01d693b2d4365cd89e42ad9c531a939b default@    │ ◉  a1896a17282f19089a5cec44358d6609910e0513 secondary@    ├─╯    ◉  c0d4a99ef98ada7da8dc73a778bbb747c4178385    ◉  0000000000000000000000000000000000000000    "###);    let stderr = test_env.jj_cmd_failure(&secondary_path, &["st"]);    insta::assert_snapshot!(stderr, @r###"    Error: The working copy is stale (not updated since operation 58b580b12eee).    Hint: Run `jj workspace update-stale` to update it.    See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-working-copy for more information.    "###);    let (stdout, stderr) = test_env.jj_cmd_ok(&secondary_path, &["workspace", "update-stale"]);    // It was detected that the working copy is now stale, but clean. So no    // divergent commit should be created.    insta::assert_snapshot!(stdout, @"");    insta::assert_snapshot!(stderr, @r###"    Working copy now at: pmmvwywv a1896a17 (empty) (no description set)    Added 0 files, modified 1 files, removed 0 files    "###);    insta::assert_snapshot!(get_log_output(&test_env, &secondary_path),    @r###"    ◉  fe8f41ed01d693b2d4365cd89e42ad9c531a939b default@    │ @  a1896a17282f19089a5cec44358d6609910e0513 secondary@    ├─╯    ◉  c0d4a99ef98ada7da8dc73a778bbb747c4178385    ◉  0000000000000000000000000000000000000000    "###);} #[test]fn test_workspaces_current_op_discarded_by_other() {    let test_env = TestEnvironment::default();    // Use the local backend because GitBackend::gc() depends on the git CLI.    test_env.jj_cmd_ok(        test_env.env_root(),        &["init", "main", "--config-toml=ui.allow-init-native=true"],    );    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"]);     // Create an op by abandoning the parent commit. Importantly, that commit also    // changes the target tree in the secondary workspace.    test_env.jj_cmd_ok(&main_path, &["abandon", "@-"]);     let stdout = test_env.jj_cmd_success(        &main_path,        &[            "operation",            "log",            "--template",            r#"id.short(10) ++ " " ++ description"#,        ],    );    insta::assert_snapshot!(stdout, @r###"    @  f1dc1bf396 abandon commit acb4b92517b20aa4ee2f3dc58d7c2373754d0b29a3df310dbabda5813f13c3730d28d6a1b6dd37f3b0c8c5c9adaead5dab242ffe7ecc2e5a6a534fe4c6639f89    ◉  47f1ad5e1a Create initial working-copy commit in workspace secondary    ◉  fd918ce207 add workspace 'secondary'    ◉  5927500c4b new empty commit    ◉  c86cb4fdf4 snapshot working copy    ◉  17dbb2fe40 add workspace 'default'    ◉  cecfee9647 initialize repo    ◉  0000000000    "###);     // Abandon ops, including the one the secondary workspace is currently on.    test_env.jj_cmd_ok(&main_path, &["operation", "abandon", "..@-"]);    test_env.jj_cmd_ok(&main_path, &["util", "gc", "--expire=now"]);     insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    @  6dc8f254cd3cbe5c086fb99adc66724303d7ceb12790e585e5946940dffca60dbb928b852e3c309b20dee351df5897f49b83c89d583a756fd736772b3e5f206a default@    │ ◉  4278b78fb503846224c4328785f8557558aab32b1e3d6ad6b343e94575dd5c67492acea9aa1c417817b4943e78547877e031208a51f8eadcd1ac55d6ebe77983 secondary@    ├─╯    ◉  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000    "###);     let stderr = test_env.jj_cmd_failure(&secondary_path, &["st"]);    insta::assert_snapshot!(stderr, @r###"    Error: Could not read working copy's operation.    Hint: Run `jj workspace update-stale` to recover.    See https://github.com/martinvonz/jj/blob/main/docs/working-copy.md#stale-working-copy for more information.    "###);     let (stdout, stderr) = test_env.jj_cmd_ok(&secondary_path, &["workspace", "update-stale"]);    insta::assert_snapshot!(stderr, @r###"    Failed to read working copy's current operation; attempting recovery. Error message from read attempt: Object 47f1ad5e1adfaa1e9863181e6e45ae12b9db553e82bde82e278c0c6288053c833b4039a5baf2415871964bcdcd4b7875692979e66f2ec18bfc3896355091cf53 of type operation not found    Created and checked out recovery commit df3e46148439    "###);    insta::assert_snapshot!(stdout, @"");     insta::assert_snapshot!(get_log_output(&test_env, &main_path), @r###"    ◉  54400d0c58b790c53de57a1c28090d23739010b300ac17cb47c26d1e48d41bb6583c94a5e4e71b32bbe1e50190c67141525e92aba9ae7b7a413ed1c989629874 secondary@    ◉  4278b78fb503846224c4328785f8557558aab32b1e3d6ad6b343e94575dd5c67492acea9aa1c417817b4943e78547877e031208a51f8eadcd1ac55d6ebe77983    │ @  6dc8f254cd3cbe5c086fb99adc66724303d7ceb12790e585e5946940dffca60dbb928b852e3c309b20dee351df5897f49b83c89d583a756fd736772b3e5f206a default@    ├─╯    ◉  00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000    "###);     let (stdout, stderr) = test_env.jj_cmd_ok(&secondary_path, &["st"]);    insta::assert_snapshot!(stderr, @"");    insta::assert_snapshot!(stdout, @r###"    Working copy changes:    A file    Working copy : znkkpsqq 54400d0c (no description set)    Parent commit: pmmvwywv 4278b78f (empty) (no description set)    "###);     let (stdout, stderr) = test_env.jj_cmd_ok(&secondary_path, &["obslog"]);    insta::assert_snapshot!(stderr, @"");    insta::assert_snapshot!(stdout, @r###"    @  znkkpsqq test.user@example.com 2001-02-03 04:05:16.000 +07:00 secondary@ 54400d0c    │  (no description set)    ◉  znkkpsqq hidden test.user@example.com 2001-02-03 04:05:16.000 +07:00 df3e4614       (empty) (no description set)    "###);} 

Lines 1–500 of 757.