ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: implement workspace add --sparse-patterns

This flag implements three modes:

- `copy`: copy sparse patterns from parent
- `full`: do not copy sparse patterns from parent
- `empty`: clear all paths, equal to `set --clear`

This is useful for various tooling like tools that want to run a parallel
process that queries the build system (without running into locks/blocking.)

I think continuing to copy sparse patterns makes sense as the default behavior.

Signed-off-by: Austin Seipp <aseipp@pobox.com>
This commit is contained in:
Austin Seipp 2024-09-06 11:48:57 -05:00
parent a677d2adfa
commit a31fe7f6d6
4 changed files with 94 additions and 14 deletions

View file

@ -24,6 +24,11 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
can be used to more easily introduce automatic formatting changes in a new
commit separate from other changes.
* `jj workspace add` now accepts a `--sparse-patterns=<MODE>` option, which
allows control of the sparse patterns for a newly created workspace: `copy`
(inherit from parent; default), `full` (full working copy), or `empty` (the
empty working copy).
### Fixed bugs
* Fixed panic when parsing invalid conflict markers of a particular form.

View file

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::fmt::Display;
use std::fs;
use itertools::Itertools;
@ -31,9 +32,31 @@ use crate::command_error::user_error;
use crate::command_error::CommandError;
use crate::ui::Ui;
/// How to handle sparse patterns when creating a new workspace.
#[derive(clap::ValueEnum, Clone, Debug, Eq, PartialEq)]
enum SparseInheritance {
/// Copy all sparse patterns from the current workspace.
Copy,
/// Include all files in the new workspace.
Full,
/// Clear all files from the workspace (it will be empty).
Empty,
}
impl Display for SparseInheritance {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SparseInheritance::Copy => write!(f, "copy"),
SparseInheritance::Full => write!(f, "full"),
SparseInheritance::Empty => write!(f, "empty"),
}
}
}
/// Add a workspace
///
/// Sparse patterns will be copied over from the current workspace.
/// By default, the new workspace inherits the sparse patterns of the current
/// workspace. You can override this with the `--sparse-patterns` option.
#[derive(clap::Args, Clone, Debug)]
pub struct WorkspaceAddArgs {
/// Where to create the new workspace
@ -58,6 +81,9 @@ pub struct WorkspaceAddArgs {
/// new r1 r2 r3 ...`.
#[arg(long, short)]
revision: Vec<RevisionArg>,
/// How to handle sparse patterns when creating a new workspace.
#[arg(long, default_value_t=SparseInheritance::Copy)]
sparse_patterns: SparseInheritance,
}
#[instrument(skip_all)]
@ -114,19 +140,29 @@ pub fn cmd_workspace_add(
)?;
}
// Copy sparse patterns from workspace where the command was run
let mut new_workspace_command = command.for_workable_repo(ui, new_workspace, repo)?;
let (mut locked_ws, _wc_commit) = new_workspace_command.start_working_copy_mutation()?;
let sparse_patterns = old_workspace_command
.working_copy()
.sparse_patterns()?
.to_vec();
locked_ws
.locked_wc()
.set_sparse_patterns(sparse_patterns)
.map_err(|err| internal_error_with_message("Failed to set sparse patterns", err))?;
let operation_id = locked_ws.locked_wc().old_operation_id().clone();
locked_ws.finish(operation_id)?;
let sparsity = match args.sparse_patterns {
SparseInheritance::Full => None,
SparseInheritance::Empty => Some(vec![]),
SparseInheritance::Copy => {
let sparse_patterns = old_workspace_command
.working_copy()
.sparse_patterns()?
.to_vec();
Some(sparse_patterns)
}
};
if let Some(sparse_patterns) = sparsity {
let (mut locked_ws, _wc_commit) = new_workspace_command.start_working_copy_mutation()?;
locked_ws
.locked_wc()
.set_sparse_patterns(sparse_patterns)
.map_err(|err| internal_error_with_message("Failed to set sparse patterns", err))?;
let operation_id = locked_ws.locked_wc().old_operation_id().clone();
locked_ws.finish(operation_id)?;
}
let mut tx = new_workspace_command.start_transaction();

View file

@ -2118,7 +2118,7 @@ Each workspace also has own sparse patterns.
Add a workspace
Sparse patterns will be copied over from the current workspace.
By default, the new workspace inherits the sparse patterns of the current workspace. You can override this with the `--sparse-patterns` option.
**Usage:** `jj workspace add [OPTIONS] <DESTINATION>`
@ -2136,6 +2136,18 @@ Sparse patterns will be copied over from the current workspace.
If no revisions are specified, the new workspace will be created, and its working-copy commit will exist on top of the parent(s) of the working-copy commit in the current workspace, i.e. they will share the same parent(s).
If any revisions are specified, the new workspace will be created, and the new working-copy commit will be created with all these revisions as parents, i.e. the working-copy commit will exist as if you had run `jj new r1 r2 r3 ...`.
* `--sparse-patterns <SPARSE_PATTERNS>` — How to handle sparse patterns when creating a new workspace
Default value: `copy`
Possible values:
- `copy`:
Copy all sparse patterns from the current workspace
- `full`:
Include all files in the new workspace
- `empty`:
Clear all files from the workspace (it will be empty)

View file

@ -77,6 +77,9 @@ fn test_workspaces_sparse_patterns() {
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"]);
@ -91,6 +94,30 @@ fn test_workspaces_sparse_patterns() {
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