forked from mirrors/jj
cli: make jj merge
delegate to jj new
This commit is contained in:
parent
d3286c2847
commit
3a46623446
3 changed files with 34 additions and 58 deletions
|
@ -30,6 +30,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
* `jj new` now always checks out the new commit (used to be only if the parent
|
||||
was `@`).
|
||||
|
||||
* `jj merge` now checks out the new commit. The command now behaves exactly
|
||||
like `jj new`, except that it requires at least two arguments.
|
||||
|
||||
|
||||
* When the working-copy commit is abandoned by `jj abandon` and the parent
|
||||
commit is open, a new working-copy commit will be created on top (the open
|
||||
parent commit used to get checked out).
|
||||
|
@ -141,8 +145,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
* `jj checkout` now lets you specify a description with `--message/-m`.
|
||||
|
||||
* `jj merge` now outputs the id of the newly created commit.
|
||||
|
||||
* `jj new` can now be used for creating merge commits. If you pass more than
|
||||
one argument to it, the new commit will have all of them as parents.
|
||||
|
||||
|
|
|
@ -1114,7 +1114,16 @@ enum Commands {
|
|||
Restore(RestoreArgs),
|
||||
Touchup(TouchupArgs),
|
||||
Split(SplitArgs),
|
||||
Merge(MergeArgs),
|
||||
/// Merge work from multiple branches
|
||||
///
|
||||
/// Unlike most other VCSs, `jj merge` does not implicitly include the
|
||||
/// working copy revision's parent as one of the parents of the merge;
|
||||
/// you need to explicitly list all revisions that should become parents
|
||||
/// of the merge.
|
||||
///
|
||||
/// This is the same as `jj new`, except that it requires at least two
|
||||
/// arguments.
|
||||
Merge(NewArgs),
|
||||
Rebase(RebaseArgs),
|
||||
Backout(BackoutArgs),
|
||||
#[clap(subcommand)]
|
||||
|
@ -1541,20 +1550,6 @@ struct SplitArgs {
|
|||
paths: Vec<String>,
|
||||
}
|
||||
|
||||
/// Merge work from multiple branches
|
||||
///
|
||||
/// Unlike most other VCSs, `jj merge` does not implicitly include the working
|
||||
/// copy revision's parent as one of the parents of the merge; you need to
|
||||
/// explicitly list all revisions that should become parents of the merge. Also,
|
||||
/// you need to explicitly check out the resulting revision if you want to.
|
||||
#[derive(clap::Args, Clone, Debug)]
|
||||
struct MergeArgs {
|
||||
revisions: Vec<String>,
|
||||
/// The change description to use (don't open editor)
|
||||
#[clap(long, short)]
|
||||
message: Option<String>,
|
||||
}
|
||||
|
||||
/// Move revisions to a different parent
|
||||
///
|
||||
/// There are three different ways of specifying which revisions to rebase:
|
||||
|
@ -3956,50 +3951,13 @@ any changes, then the operation will be aborted.
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_merge(ui: &mut Ui, command: &CommandHelper, args: &MergeArgs) -> Result<(), CommandError> {
|
||||
let mut workspace_command = command.workspace_helper(ui)?;
|
||||
let revision_args = &args.revisions;
|
||||
if revision_args.len() < 2 {
|
||||
return Err(CommandError::UserError(String::from(
|
||||
fn cmd_merge(ui: &mut Ui, command: &CommandHelper, args: &NewArgs) -> Result<(), CommandError> {
|
||||
if args.revisions.len() < 2 {
|
||||
return Err(CommandError::CliError(String::from(
|
||||
"Merge requires at least two revisions",
|
||||
)));
|
||||
}
|
||||
let mut commits = vec![];
|
||||
let mut parent_ids = vec![];
|
||||
for revision_arg in revision_args {
|
||||
// TODO: Should we allow each argument to resolve to multiple revisions?
|
||||
// It would be neat to be able to do `jj merge main` when `main` is conflicted,
|
||||
// but I'm not sure it would actually be useful.
|
||||
let commit = workspace_command.resolve_single_rev(revision_arg)?;
|
||||
parent_ids.push(commit.id().clone());
|
||||
commits.push(commit);
|
||||
}
|
||||
let description = if let Some(message) = &args.message {
|
||||
message.to_string()
|
||||
} else {
|
||||
edit_description(
|
||||
ui,
|
||||
workspace_command.repo(),
|
||||
"\n\nJJ: Enter commit description for the merge commit.\n",
|
||||
)?
|
||||
};
|
||||
let merged_tree = merge_commit_trees(workspace_command.repo().as_repo_ref(), &commits);
|
||||
let mut tx = workspace_command.start_transaction("merge commits");
|
||||
let new_commit = CommitBuilder::for_new_commit(ui.settings(), merged_tree.id().clone())
|
||||
.set_parents(parent_ids)
|
||||
.set_description(description)
|
||||
.set_open(false)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
ui.write("Created merge commit: ")?;
|
||||
ui.write_commit_summary(
|
||||
workspace_command.repo().as_repo_ref(),
|
||||
&workspace_command.workspace_id(),
|
||||
&new_commit,
|
||||
)?;
|
||||
ui.write("\n")?;
|
||||
workspace_command.finish_transaction(ui, tx)?;
|
||||
|
||||
Ok(())
|
||||
cmd_new(ui, command, args)
|
||||
}
|
||||
|
||||
fn cmd_rebase(ui: &mut Ui, command: &CommandHelper, args: &RebaseArgs) -> Result<(), CommandError> {
|
||||
|
|
|
@ -70,6 +70,22 @@ fn test_new_merge() {
|
|||
insta::assert_snapshot!(stdout, @"a");
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["print", "file2"]);
|
||||
insta::assert_snapshot!(stdout, @"b");
|
||||
|
||||
// Same test with `jj merge`
|
||||
test_env.jj_cmd_success(&repo_path, &["undo"]);
|
||||
test_env.jj_cmd_success(&repo_path, &["merge", "main", "@"]);
|
||||
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###"
|
||||
@ c34d60aa33225c2080da52faa39980efe944bddd (no description set)
|
||||
|\
|
||||
o | 99814c62bec5c13d2053435b3d6bbeb1900cb57e add file2
|
||||
| o fe37af248a068697c6dcd7ebd17f5aac2205e7cb add file1
|
||||
|/
|
||||
o 0000000000000000000000000000000000000000 (no description set)
|
||||
"###);
|
||||
|
||||
// `jj merge` with less than two arguments is an error
|
||||
test_env.jj_cmd_cli_error(&repo_path, &["merge"]);
|
||||
test_env.jj_cmd_cli_error(&repo_path, &["merge", "main"]);
|
||||
}
|
||||
|
||||
fn get_log_output(test_env: &TestEnvironment, repo_path: &Path) -> String {
|
||||
|
|
Loading…
Reference in a new issue