Skip to content

Commit

Permalink
cli: support multiple --revision arguments to workspace add
Browse files Browse the repository at this point in the history
Summary: A natural extension of the existing support, as suggested by Scott
Olson. Closes #2496.

Signed-off-by: Austin Seipp <[email protected]>
Change-Id: I91c9c8c377ad67ccde7945ed41af6c79
  • Loading branch information
thoughtpolice committed Nov 3, 2023
1 parent d8a845d commit d421194
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### New features

* `jj workspace add` can now take _multiple_ `--revision` arguments, which if
provided will create a new workspace on top of the merge commit of all the
given parents.

### Fixed bugs


Expand Down
22 changes: 16 additions & 6 deletions cli/src/commands/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,15 @@ pub struct WorkspaceAddArgs {
/// directory.
#[arg(long)]
name: Option<String>,
/// The revision that the workspace should be created at; a new working copy
/// commit will be created on top of it.
/// A list of parents that that the workspace should be created from; a new
/// working copy commit will be created on top of them. If a single commit
/// is provided, the working copy is put on top. If multiple commits are
/// provided, they will be merged together and a working copy commit will be
/// created on top of the merge commit. If no parents are provided, the new
/// working copy commit will be created on top of the current workspace's
/// working copy commit.
#[arg(long, short)]
revision: Option<RevisionArg>,
revision: Vec<RevisionArg>,
}

/// Stop tracking a workspace's working-copy commit in the repo
Expand Down Expand Up @@ -166,9 +171,9 @@ fn cmd_workspace_add(
&name
));

let parents = if let Some(specific_rev) = &args.revision {
vec![old_workspace_command.resolve_single_rev(specific_rev, ui)?]
} else {
// check if args.revision is empty, and if so, create a working copy based
// on the existing one
let parents = if args.revision.is_empty() {
// Check out parents of the current workspace's working-copy commit, or the
// root if there is no working-copy commit in the current workspace.
if let Some(old_wc_commit_id) = tx
Expand All @@ -180,6 +185,11 @@ fn cmd_workspace_add(
} else {
vec![tx.repo().store().root_commit()]
}
} else {
args.revision
.iter()
.map(|rev| old_workspace_command.resolve_single_rev(rev, ui))
.collect::<Result<Vec<_>, _>>()?
};

let tree = merge_commit_trees(tx.repo(), &parents)?;
Expand Down
70 changes: 70 additions & 0 deletions cli/tests/test_workspaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,76 @@ fn test_workspaces_add_workspace_at_revision() {
"###);
}

/// Test using multiple `workspace add -r` commands to create a workspace at
/// a merge commit.
#[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]
Expand Down

0 comments on commit d421194

Please sign in to comment.