mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-15 00:44:33 +00:00
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:
parent
a677d2adfa
commit
a31fe7f6d6
4 changed files with 94 additions and 14 deletions
|
@ -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
|
can be used to more easily introduce automatic formatting changes in a new
|
||||||
commit separate from other changes.
|
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 bugs
|
||||||
|
|
||||||
* Fixed panic when parsing invalid conflict markers of a particular form.
|
* Fixed panic when parsing invalid conflict markers of a particular form.
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
|
use std::fmt::Display;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
@ -31,9 +32,31 @@ use crate::command_error::user_error;
|
||||||
use crate::command_error::CommandError;
|
use crate::command_error::CommandError;
|
||||||
use crate::ui::Ui;
|
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
|
/// 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)]
|
#[derive(clap::Args, Clone, Debug)]
|
||||||
pub struct WorkspaceAddArgs {
|
pub struct WorkspaceAddArgs {
|
||||||
/// Where to create the new workspace
|
/// Where to create the new workspace
|
||||||
|
@ -58,6 +81,9 @@ pub struct WorkspaceAddArgs {
|
||||||
/// new r1 r2 r3 ...`.
|
/// new r1 r2 r3 ...`.
|
||||||
#[arg(long, short)]
|
#[arg(long, short)]
|
||||||
revision: Vec<RevisionArg>,
|
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)]
|
#[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 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
|
let sparsity = match args.sparse_patterns {
|
||||||
.working_copy()
|
SparseInheritance::Full => None,
|
||||||
.sparse_patterns()?
|
SparseInheritance::Empty => Some(vec![]),
|
||||||
.to_vec();
|
SparseInheritance::Copy => {
|
||||||
locked_ws
|
let sparse_patterns = old_workspace_command
|
||||||
.locked_wc()
|
.working_copy()
|
||||||
.set_sparse_patterns(sparse_patterns)
|
.sparse_patterns()?
|
||||||
.map_err(|err| internal_error_with_message("Failed to set sparse patterns", err))?;
|
.to_vec();
|
||||||
let operation_id = locked_ws.locked_wc().old_operation_id().clone();
|
Some(sparse_patterns)
|
||||||
locked_ws.finish(operation_id)?;
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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();
|
let mut tx = new_workspace_command.start_transaction();
|
||||||
|
|
||||||
|
|
|
@ -2118,7 +2118,7 @@ Each workspace also has own sparse patterns.
|
||||||
|
|
||||||
Add a workspace
|
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>`
|
**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 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 ...`.
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ fn test_workspaces_sparse_patterns() {
|
||||||
let ws1_path = test_env.env_root().join("ws1");
|
let ws1_path = test_env.env_root().join("ws1");
|
||||||
let ws2_path = test_env.env_root().join("ws2");
|
let ws2_path = test_env.env_root().join("ws2");
|
||||||
let ws3_path = test_env.env_root().join("ws3");
|
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, &["sparse", "set", "--clear", "--add=foo"]);
|
||||||
test_env.jj_cmd_ok(&ws1_path, &["workspace", "add", "../ws2"]);
|
test_env.jj_cmd_ok(&ws1_path, &["workspace", "add", "../ws2"]);
|
||||||
|
@ -91,6 +94,30 @@ fn test_workspaces_sparse_patterns() {
|
||||||
bar
|
bar
|
||||||
foo
|
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
|
/// Test adding a second workspace while the current workspace is editing a
|
||||||
|
|
Loading…
Reference in a new issue