2023-10-29 18:08:38 +00:00
|
|
|
// Copyright 2020 The Jujutsu Authors
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
use clap::ArgGroup;
|
2024-01-04 07:18:04 +00:00
|
|
|
use jj_lib::object_id::ObjectId;
|
2023-10-29 18:08:38 +00:00
|
|
|
use tracing::instrument;
|
|
|
|
|
2024-04-02 15:19:12 +00:00
|
|
|
use super::squash::{move_diff, SquashedDescription};
|
2024-03-02 04:19:26 +00:00
|
|
|
use crate::cli_util::{CommandHelper, RevisionArg};
|
|
|
|
use crate::command_error::{user_error, CommandError};
|
2023-10-29 18:08:38 +00:00
|
|
|
use crate::ui::Ui;
|
|
|
|
|
2024-06-01 19:14:25 +00:00
|
|
|
/// Move changes from one revision into another (DEPRECATED, use `jj squash`)
|
2023-10-29 18:08:38 +00:00
|
|
|
///
|
|
|
|
/// Use `--interactive` to move only part of the source revision into the
|
|
|
|
/// destination. The selected changes (or all the changes in the source revision
|
|
|
|
/// if not using `--interactive`) will be moved into the destination. The
|
|
|
|
/// changes will be removed from the source. If that means that the source is
|
|
|
|
/// now empty compared to its parent, it will be abandoned. Without
|
|
|
|
/// `--interactive`, the source change will always be empty.
|
|
|
|
///
|
|
|
|
/// If the source became empty and both the source and destination had a
|
|
|
|
/// non-empty description, you will be asked for the combined description. If
|
|
|
|
/// either was empty, then the other one will be used.
|
2024-02-26 00:39:35 +00:00
|
|
|
///
|
|
|
|
/// If a working-copy commit gets abandoned, it will be given a new, empty
|
|
|
|
/// commit. This is true in general; it is not specific to this command.
|
2023-10-29 18:08:38 +00:00
|
|
|
#[derive(clap::Args, Clone, Debug)]
|
|
|
|
#[command(group(ArgGroup::new("to_move").args(&["from", "to"]).multiple(true).required(true)))]
|
|
|
|
pub(crate) struct MoveArgs {
|
|
|
|
/// Move part of this change into the destination
|
2024-02-12 22:27:57 +00:00
|
|
|
#[arg(long, short)]
|
2023-10-29 18:08:38 +00:00
|
|
|
from: Option<RevisionArg>,
|
|
|
|
/// Move part of the source into this change
|
2024-02-12 22:27:57 +00:00
|
|
|
#[arg(long, short)]
|
2023-10-29 18:08:38 +00:00
|
|
|
to: Option<RevisionArg>,
|
|
|
|
/// Interactively choose which parts to move
|
|
|
|
#[arg(long, short)]
|
|
|
|
interactive: bool,
|
2024-03-01 14:49:22 +00:00
|
|
|
/// Specify diff editor to be used (implies --interactive)
|
|
|
|
#[arg(long, value_name = "NAME")]
|
2024-03-10 18:50:14 +00:00
|
|
|
tool: Option<String>,
|
2023-10-29 18:08:38 +00:00
|
|
|
/// Move only changes to these paths (instead of all paths)
|
2024-03-01 14:49:22 +00:00
|
|
|
#[arg(conflicts_with_all = ["interactive", "tool"], value_hint = clap::ValueHint::AnyPath)]
|
2023-10-29 18:08:38 +00:00
|
|
|
paths: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[instrument(skip_all)]
|
|
|
|
pub(crate) fn cmd_move(
|
|
|
|
ui: &mut Ui,
|
|
|
|
command: &CommandHelper,
|
|
|
|
args: &MoveArgs,
|
|
|
|
) -> Result<(), CommandError> {
|
2024-03-11 04:24:13 +00:00
|
|
|
writeln!(
|
2024-03-24 06:24:32 +00:00
|
|
|
ui.warning_default(),
|
2024-03-24 06:13:42 +00:00
|
|
|
"`jj move` is deprecated; use `jj squash` instead, which is equivalent"
|
2024-03-11 04:24:13 +00:00
|
|
|
)?;
|
|
|
|
writeln!(
|
2024-03-24 06:24:32 +00:00
|
|
|
ui.warning_default(),
|
2024-03-24 06:13:42 +00:00
|
|
|
"`jj move` will be removed in a future version, and this will be a hard error"
|
2024-03-11 04:24:13 +00:00
|
|
|
)?;
|
2023-10-29 18:08:38 +00:00
|
|
|
let mut workspace_command = command.workspace_helper(ui)?;
|
2024-04-01 07:24:57 +00:00
|
|
|
let source =
|
|
|
|
workspace_command.resolve_single_rev(args.from.as_ref().unwrap_or(&RevisionArg::AT))?;
|
|
|
|
let destination =
|
|
|
|
workspace_command.resolve_single_rev(args.to.as_ref().unwrap_or(&RevisionArg::AT))?;
|
2023-10-29 18:08:38 +00:00
|
|
|
if source.id() == destination.id() {
|
|
|
|
return Err(user_error("Source and destination cannot be the same."));
|
|
|
|
}
|
2024-04-06 09:46:08 +00:00
|
|
|
let matcher = workspace_command
|
|
|
|
.parse_file_patterns(&args.paths)?
|
|
|
|
.to_matcher();
|
2024-03-01 14:49:22 +00:00
|
|
|
let diff_selector =
|
|
|
|
workspace_command.diff_selector(ui, args.tool.as_deref(), args.interactive)?;
|
2023-12-12 05:42:05 +00:00
|
|
|
let mut tx = workspace_command.start_transaction();
|
2024-03-10 21:13:57 +00:00
|
|
|
let tx_description = format!(
|
|
|
|
"move changes from {} to {}",
|
|
|
|
source.id().hex(),
|
|
|
|
destination.id().hex()
|
|
|
|
);
|
2024-03-10 20:55:48 +00:00
|
|
|
move_diff(
|
2024-03-10 21:41:51 +00:00
|
|
|
ui,
|
2024-03-10 20:55:48 +00:00
|
|
|
&mut tx,
|
2023-10-29 18:08:38 +00:00
|
|
|
command.settings(),
|
2024-03-11 04:46:21 +00:00
|
|
|
&[source],
|
|
|
|
&destination,
|
2024-03-10 20:55:48 +00:00
|
|
|
matcher.as_ref(),
|
|
|
|
&diff_selector,
|
2024-04-02 15:19:12 +00:00
|
|
|
SquashedDescription::Combine,
|
2024-03-10 21:41:51 +00:00
|
|
|
false,
|
|
|
|
&args.paths,
|
2024-06-04 23:34:50 +00:00
|
|
|
false,
|
2023-10-29 18:08:38 +00:00
|
|
|
)?;
|
2024-03-10 21:13:57 +00:00
|
|
|
tx.finish(ui, tx_description)?;
|
2023-10-29 18:08:38 +00:00
|
|
|
Ok(())
|
|
|
|
}
|