use jj_lib::op_heads_store;
use jj_lib::operation::Operation;
use crate::cli_util::CommandHelper;
use crate::cli_util::start_repo_transaction;
use crate::command_error::CommandError;
use crate::ui::Ui;
#[derive(clap::Args, Clone, Debug)]
pub struct OperationIntegrateArgs {
operation: String,
}
pub async fn cmd_op_integrate(
ui: &mut Ui,
command: &CommandHelper,
args: &OperationIntegrateArgs,
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper_no_snapshot(ui)?;
let target_op = workspace_command.resolve_single_op(&args.operation)?;
let repo_loader = workspace_command.repo().loader();
repo_loader
.op_heads_store()
.update_op_heads(target_op.parent_ids(), target_op.id())
.await?;
op_heads_store::resolve_op_heads(
repo_loader.op_heads_store().as_ref(),
repo_loader.op_store(),
async |op_heads| -> Result<Operation, CommandError> {
let base_repo = repo_loader.load_at(&op_heads[0]).await?;
let mut tx = start_repo_transaction(
&base_repo,
workspace_command.workspace_name(),
command.string_args(),
);
for other_op_head in op_heads.into_iter().skip(1) {
tx.merge_operation(other_op_head).await?;
let num_rebased = tx.repo_mut().rebase_descendants().await?;
if num_rebased > 0 {
writeln!(
ui.status(),
"Rebased {num_rebased} descendant commits onto commits rewritten by other \
operation"
)?;
}
}
writeln!(
ui.status(),
"The specified operation has been integrated with other existing operations."
)?;
Ok(tx
.write("reconcile divergent operations")
.await?
.leave_unpublished()
.operation()
.clone())
},
)
.await?;
Ok(())
}