forked from mirrors/jj
cli: make "duplicate" evaluate source revisions all at once
There's a subtle behavior change that an empty revset is no longer rejected individually, but I think that's good for "jj duplicate". cmd_duplicate() was the last caller of index.topo_order().
This commit is contained in:
parent
a1b3b3c547
commit
4e3c772428
2 changed files with 24 additions and 21 deletions
|
@ -14,14 +14,13 @@
|
|||
|
||||
use std::io::Write;
|
||||
|
||||
use indexmap::{IndexMap, IndexSet};
|
||||
use indexmap::IndexMap;
|
||||
use jj_lib::backend::CommitId;
|
||||
use jj_lib::commit::Commit;
|
||||
use jj_lib::repo::Repo;
|
||||
use tracing::instrument;
|
||||
|
||||
use crate::cli_util::{
|
||||
resolve_multiple_nonempty_revsets, short_commit_hash, CommandHelper, RevisionArg,
|
||||
};
|
||||
use crate::cli_util::{short_commit_hash, CommandHelper, RevisionArg};
|
||||
use crate::command_error::{user_error, CommandError};
|
||||
use crate::ui::Ui;
|
||||
|
||||
|
@ -43,12 +42,15 @@ pub(crate) fn cmd_duplicate(
|
|||
args: &DuplicateArgs,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut workspace_command = command.workspace_helper(ui)?;
|
||||
let to_duplicate: IndexSet<Commit> =
|
||||
resolve_multiple_nonempty_revsets(&args.revisions, &workspace_command)?;
|
||||
if to_duplicate
|
||||
.iter()
|
||||
.any(|commit| commit.id() == workspace_command.repo().store().root_commit_id())
|
||||
{
|
||||
let to_duplicate: Vec<CommitId> = {
|
||||
let expression = workspace_command.parse_union_revsets(&args.revisions)?;
|
||||
let revset = workspace_command.evaluate_revset(expression)?;
|
||||
revset.iter().collect() // in reverse topological order
|
||||
};
|
||||
if to_duplicate.is_empty() {
|
||||
return Err(user_error("No revisions to duplicate"));
|
||||
}
|
||||
if to_duplicate.last() == Some(workspace_command.repo().store().root_commit_id()) {
|
||||
return Err(user_error("Cannot duplicate the root commit"));
|
||||
}
|
||||
let mut duplicated_old_to_new: IndexMap<Commit, Commit> = IndexMap::new();
|
||||
|
@ -58,14 +60,10 @@ pub(crate) fn cmd_duplicate(
|
|||
let store = base_repo.store();
|
||||
let mut_repo = tx.mut_repo();
|
||||
|
||||
for original_commit_id in base_repo
|
||||
.index()
|
||||
.topo_order(&mut to_duplicate.iter().map(|c| c.id()))
|
||||
.into_iter()
|
||||
{
|
||||
for original_commit_id in to_duplicate.iter().rev() {
|
||||
// Topological order ensures that any parents of `original_commit` are
|
||||
// either not in `to_duplicate` or were already duplicated.
|
||||
let original_commit = store.get_commit(&original_commit_id).unwrap();
|
||||
let original_commit = store.get_commit(original_commit_id).unwrap();
|
||||
let new_parents = original_commit
|
||||
.parents()
|
||||
.iter()
|
||||
|
|
|
@ -47,18 +47,23 @@ fn test_duplicate() {
|
|||
◉ 000000000000
|
||||
"###);
|
||||
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["duplicate", "root()"]);
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["duplicate", "all()"]);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Error: Cannot duplicate the root commit
|
||||
"###);
|
||||
|
||||
let stderr = test_env.jj_cmd_failure(&repo_path, &["duplicate", "none()"]);
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Error: No revisions to duplicate
|
||||
"###);
|
||||
|
||||
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["duplicate", "a"]);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Duplicated 2443ea76b0b1 as znkkpsqq 2f6dc5a1 a
|
||||
Duplicated 2443ea76b0b1 as kpqxywon f5b1e687 a
|
||||
"###);
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
|
||||
◉ 2f6dc5a1ffc2 a
|
||||
◉ f5b1e68729d6 a
|
||||
│ @ 17a00fc21654 c
|
||||
│ ├─╮
|
||||
│ │ ◉ d370aee184ba b
|
||||
|
@ -74,10 +79,10 @@ fn test_duplicate() {
|
|||
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["duplicate" /* duplicates `c` */]);
|
||||
insta::assert_snapshot!(stdout, @"");
|
||||
insta::assert_snapshot!(stderr, @r###"
|
||||
Duplicated 17a00fc21654 as wqnwkozp 1dd099ea c
|
||||
Duplicated 17a00fc21654 as lylxulpl ef3b0f3d c
|
||||
"###);
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
|
||||
◉ 1dd099ea963c c
|
||||
◉ ef3b0f3d1046 c
|
||||
├─╮
|
||||
│ │ @ 17a00fc21654 c
|
||||
╭─┬─╯
|
||||
|
|
Loading…
Reference in a new issue