diff --git a/cli/tests/test_git_clone.rs b/cli/tests/test_git_clone.rs index 7ca1f50551..0d3d2dba47 100644 --- a/cli/tests/test_git_clone.rs +++ b/cli/tests/test_git_clone.rs @@ -442,6 +442,61 @@ fn test_git_clone_remote_default_branch() { "###); } +#[test] +fn test_git_clone_ignore_working_copy() { + let test_env = TestEnvironment::default(); + let git_repo_path = test_env.env_root().join("source"); + let git_repo = git2::Repository::init(git_repo_path).unwrap(); + set_up_non_empty_git_repo(&git_repo); + + // Should not update working-copy files + let (_stdout, stderr) = test_env.jj_cmd_ok( + test_env.env_root(), + &["git", "clone", "--ignore-working-copy", "source", "clone"], + ); + insta::assert_snapshot!(stderr, @r###" + Fetching into new repo in "$TEST_ENV/clone" + branch: main@origin [new] untracked + Setting the revset alias "trunk()" to "main@origin" + "###); + let clone_path = test_env.env_root().join("clone"); + + let (stdout, stderr) = test_env.jj_cmd_ok(&clone_path, &["status", "--ignore-working-copy"]); + insta::assert_snapshot!(stdout, @r###" + The working copy is clean + Working copy : sqpuoqvx cad212e1 (empty) (no description set) + Parent commit: mzyxwzks 9f01a0e0 main | message + "###); + insta::assert_snapshot!(stderr, @""); + + // TODO: Correct, but might be better to check out the root commit? + let stderr = test_env.jj_cmd_failure(&clone_path, &["status"]); + insta::assert_snapshot!(stderr, @r###" + Error: The working copy is stale (not updated since operation b51416386f26). + 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. + "###); +} + +#[test] +fn test_git_clone_at_operation() { + let test_env = TestEnvironment::default(); + let git_repo_path = test_env.env_root().join("source"); + let git_repo = git2::Repository::init(git_repo_path).unwrap(); + set_up_non_empty_git_repo(&git_repo); + + // TODO: just error out? no operation should exist + let (_stdout, stderr) = test_env.jj_cmd_ok( + test_env.env_root(), + &["git", "clone", "--at-op=@-", "source", "clone"], + ); + insta::assert_snapshot!(stderr, @r###" + Fetching into new repo in "$TEST_ENV/clone" + branch: main@origin [new] untracked + Setting the revset alias "trunk()" to "main@origin" + "###); +} + fn get_branch_output(test_env: &TestEnvironment, repo_path: &Path) -> String { test_env.jj_cmd_success(repo_path, &["branch", "list", "--all-remotes"]) } diff --git a/cli/tests/test_git_init.rs b/cli/tests/test_git_init.rs index 6aca4887ac..ea37f312b2 100644 --- a/cli/tests/test_git_init.rs +++ b/cli/tests/test_git_init.rs @@ -94,6 +94,43 @@ fn test_git_init_internal() { assert_eq!(read_git_target(&workspace_root), "git"); } +#[test] +fn test_git_init_internal_ignore_working_copy() { + let test_env = TestEnvironment::default(); + let workspace_root = test_env.env_root().join("repo"); + std::fs::create_dir(&workspace_root).unwrap(); + std::fs::write(workspace_root.join("file1"), "").unwrap(); + + // No snapshot should be taken + let (_stdout, stderr) = + test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--ignore-working-copy"]); + insta::assert_snapshot!(stderr, @r###" + Initialized repo in "." + "###); + + let (stdout, stderr) = + test_env.jj_cmd_ok(&workspace_root, &["status", "--ignore-working-copy"]); + insta::assert_snapshot!(stdout, @r###" + The working copy is clean + Working copy : qpvuntsm 230dd059 (empty) (no description set) + Parent commit: zzzzzzzz 00000000 (empty) (no description set) + "###); + insta::assert_snapshot!(stderr, @""); +} + +#[test] +fn test_git_init_internal_at_operation() { + let test_env = TestEnvironment::default(); + let workspace_root = test_env.env_root().join("repo"); + std::fs::create_dir(&workspace_root).unwrap(); + + // TODO: just error out? no operation should exist + let (_stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["git", "init", "--at-op=@-"]); + insta::assert_snapshot!(stderr, @r###" + Initialized repo in "." + "###); +} + #[test_case(false; "full")] #[test_case(true; "bare")] fn test_git_init_external(bare: bool) { @@ -207,6 +244,74 @@ fn test_git_init_external_import_trunk(bare: bool) { } } +#[test] +fn test_git_init_external_ignore_working_copy() { + let test_env = TestEnvironment::default(); + let git_repo_path = test_env.env_root().join("git-repo"); + init_git_repo(&git_repo_path, false); + let workspace_root = test_env.env_root().join("repo"); + std::fs::create_dir(&workspace_root).unwrap(); + std::fs::write(workspace_root.join("file1"), "").unwrap(); + + // No snapshot should be taken + let (_stdout, stderr) = test_env.jj_cmd_ok( + &workspace_root, + &[ + "git", + "init", + "--ignore-working-copy", + "--git-repo", + git_repo_path.to_str().unwrap(), + ], + ); + insta::assert_snapshot!(stderr, @r###" + Done importing changes from the underlying Git repo. + Initialized repo in "." + "###); + + let (stdout, stderr) = + test_env.jj_cmd_ok(&workspace_root, &["status", "--ignore-working-copy"]); + insta::assert_snapshot!(stdout, @r###" + The working copy is clean + Working copy : sqpuoqvx f6950fc1 (empty) (no description set) + Parent commit: mwrttmos 8d698d4a my-branch | My commit message + "###); + insta::assert_snapshot!(stderr, @""); + + // TODO: Correct, but might be better to check out the root commit? + let stderr = test_env.jj_cmd_failure(&workspace_root, &["status"]); + insta::assert_snapshot!(stderr, @r###" + Error: The working copy is stale (not updated since operation b51416386f26). + 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. + "###); +} + +#[test] +fn test_git_init_external_at_operation() { + let test_env = TestEnvironment::default(); + let git_repo_path = test_env.env_root().join("git-repo"); + init_git_repo(&git_repo_path, false); + let workspace_root = test_env.env_root().join("repo"); + std::fs::create_dir(&workspace_root).unwrap(); + + // TODO: just error out? no operation should exist + let (_stdout, stderr) = test_env.jj_cmd_ok( + &workspace_root, + &[ + "git", + "init", + "--at-op=@-", + "--git-repo", + git_repo_path.to_str().unwrap(), + ], + ); + insta::assert_snapshot!(stderr, @r###" + Done importing changes from the underlying Git repo. + Initialized repo in "." + "###); +} + #[test] fn test_git_init_external_non_existent_directory() { let test_env = TestEnvironment::default(); @@ -564,6 +669,61 @@ fn test_git_init_colocated_dirty_working_copy() { "###); } +#[test] +fn test_git_init_colocated_ignore_working_copy() { + let test_env = TestEnvironment::default(); + let workspace_root = test_env.env_root().join("repo"); + init_git_repo(&workspace_root, false); + std::fs::write(workspace_root.join("file1"), "").unwrap(); + + // No snapshot should be taken + let (_stdout, stderr) = test_env.jj_cmd_ok( + &workspace_root, + &["git", "init", "--ignore-working-copy", "--colocate"], + ); + insta::assert_snapshot!(stderr, @r###" + Done importing changes from the underlying Git repo. + Initialized repo in "." + "###); + + // FIXME: wrong HEAD, but fixing this would result in stale working copy + let (stdout, stderr) = + test_env.jj_cmd_ok(&workspace_root, &["status", "--ignore-working-copy"]); + insta::assert_snapshot!(stdout, @r###" + The working copy is clean + Working copy : qpvuntsm 230dd059 (empty) (no description set) + Parent commit: zzzzzzzz 00000000 (empty) (no description set) + "###); + insta::assert_snapshot!(stderr, @""); + + let (stdout, stderr) = test_env.jj_cmd_ok(&workspace_root, &["status"]); + insta::assert_snapshot!(stdout, @r###" + Working copy changes: + A file1 + D some-file + Working copy : kkmpptxz 7864ea63 (no description set) + Parent commit: mwrttmos 8d698d4a my-branch | My commit message + "###); + insta::assert_snapshot!(stderr, @""); +} + +#[test] +fn test_git_init_colocated_at_operation() { + let test_env = TestEnvironment::default(); + let workspace_root = test_env.env_root().join("repo"); + init_git_repo(&workspace_root, false); + + // TODO: just error out? no operation should exist + let (_stdout, stderr) = test_env.jj_cmd_ok( + &workspace_root, + &["git", "init", "--at-op=@-", "--colocate"], + ); + insta::assert_snapshot!(stderr, @r###" + Done importing changes from the underlying Git repo. + Initialized repo in "." + "###); +} + #[test] fn test_git_init_external_but_git_dir_exists() { let test_env = TestEnvironment::default(); diff --git a/cli/tests/test_workspaces.rs b/cli/tests/test_workspaces.rs index bedf2d3421..874f8f5940 100644 --- a/cli/tests/test_workspaces.rs +++ b/cli/tests/test_workspaces.rs @@ -128,6 +128,90 @@ fn test_workspaces_add_second_workspace_on_merge() { "###); } +/// 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 + "###); + + // FIXME: --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 stderr = test_env.jj_cmd_failure( + &main_path, + &["workspace", "add", "--at-op=@-", "../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 --at-op. + "###); + 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 : zsuskuln 7df5cfc8 (no description set) + Parent commit: zzzzzzzz 00000000 (empty) (no description set) + "###); + 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 + ○ resolve concurrent operations + ├─╮ + ○ │ commit cd06097124e3e5860867e35c2bb105902c28ea38 + │ ○ add workspace 'secondary' + ├─╯ + ○ snapshot working copy + ○ commit 1c867a0762e30de4591890ea208849f793742c1b + ○ snapshot working copy + ○ add workspace 'default' + ○ initialize repo + ○ + "###); +} + /// Test adding a workspace, but at a specific revision using '-r' #[test] fn test_workspaces_add_workspace_at_revision() {