From af2d6c67f13a87b92f4180b465f0ccd968ed5779 Mon Sep 17 00:00:00 2001 From: Antoine Cezar Date: Thu, 26 Oct 2023 17:39:04 +0200 Subject: [PATCH] commands: move abandon code to abandon.rs --- cli/src/commands/abandon.rs | 91 +++++++++++++++++++++++++++++++++++++ cli/src/commands/mod.rs | 73 ++--------------------------- 2 files changed, 94 insertions(+), 70 deletions(-) create mode 100644 cli/src/commands/abandon.rs diff --git a/cli/src/commands/abandon.rs b/cli/src/commands/abandon.rs new file mode 100644 index 000000000..cdacb10c9 --- /dev/null +++ b/cli/src/commands/abandon.rs @@ -0,0 +1,91 @@ +// 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 std::io::Write; + +use jj_lib::backend::ObjectId; +use tracing::instrument; + +use crate::cli_util::{ + resolve_multiple_nonempty_revsets, CommandError, CommandHelper, RevisionArg, +}; +use crate::ui::Ui; + +/// Abandon a revision +/// +/// Abandon a revision, rebasing descendants onto its parent(s). The behavior is +/// similar to `jj restore --changes-in`; the difference is that `jj abandon` +/// gives you a new change, while `jj restore` updates the existing change. +#[derive(clap::Args, Clone, Debug)] +pub(crate) struct AbandonArgs { + /// The revision(s) to abandon + #[arg(default_value = "@")] + revisions: Vec, + /// Do not print every abandoned commit on a separate line + #[arg(long, short)] + summary: bool, + /// Ignored (but lets you pass `-r` for consistency with other commands) + #[arg(short = 'r', hide = true)] + unused_revision: bool, +} + +#[instrument(skip_all)] +pub(crate) fn cmd_abandon( + ui: &mut Ui, + command: &CommandHelper, + args: &AbandonArgs, +) -> Result<(), CommandError> { + let mut workspace_command = command.workspace_helper(ui)?; + let to_abandon = resolve_multiple_nonempty_revsets(&args.revisions, &workspace_command, ui)?; + workspace_command.check_rewritable(to_abandon.iter())?; + let transaction_description = if to_abandon.len() == 1 { + format!("abandon commit {}", to_abandon[0].id().hex()) + } else { + format!( + "abandon commit {} and {} more", + to_abandon[0].id().hex(), + to_abandon.len() - 1 + ) + }; + let mut tx = workspace_command.start_transaction(&transaction_description); + for commit in &to_abandon { + tx.mut_repo().record_abandoned_commit(commit.id().clone()); + } + let num_rebased = tx.mut_repo().rebase_descendants(command.settings())?; + + if to_abandon.len() == 1 { + write!(ui.stderr(), "Abandoned commit ")?; + tx.base_workspace_helper() + .write_commit_summary(ui.stderr_formatter().as_mut(), &to_abandon[0])?; + writeln!(ui.stderr())?; + } else if !args.summary { + writeln!(ui.stderr(), "Abandoned the following commits:")?; + for commit in to_abandon { + write!(ui.stderr(), " ")?; + tx.base_workspace_helper() + .write_commit_summary(ui.stderr_formatter().as_mut(), &commit)?; + writeln!(ui.stderr())?; + } + } else { + writeln!(ui.stderr(), "Abandoned {} commits.", &to_abandon.len())?; + } + if num_rebased > 0 { + writeln!( + ui.stderr(), + "Rebased {num_rebased} descendant commits onto parents of abandoned commits" + )?; + } + tx.finish(ui)?; + Ok(()) +} diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index a2d901174..270003340 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +mod abandon; #[cfg(feature = "bench")] mod bench; mod branch; @@ -70,7 +71,7 @@ use crate::ui::Ui; #[derive(clap::Parser, Clone, Debug)] enum Commands { - Abandon(AbandonArgs), + Abandon(abandon::AbandonArgs), Backout(BackoutArgs), #[cfg(feature = "bench")] #[command(subcommand)] @@ -493,24 +494,6 @@ struct DuplicateArgs { unused_revision: bool, } -/// Abandon a revision -/// -/// Abandon a revision, rebasing descendants onto its parent(s). The behavior is -/// similar to `jj restore --changes-in`; the difference is that `jj abandon` -/// gives you a new change, while `jj restore` updates the existing change. -#[derive(clap::Args, Clone, Debug)] -struct AbandonArgs { - /// The revision(s) to abandon - #[arg(default_value = "@")] - revisions: Vec, - /// Do not print every abandoned commit on a separate line - #[arg(long, short)] - summary: bool, - /// Ignored (but lets you pass `-r` for consistency with other commands) - #[arg(short = 'r', hide = true)] - unused_revision: bool, -} - /// Edit a commit in the working copy /// /// Puts the contents of a commit in the working copy for editing. Any changes @@ -2295,56 +2278,6 @@ fn cmd_duplicate( Ok(()) } -#[instrument(skip_all)] -fn cmd_abandon( - ui: &mut Ui, - command: &CommandHelper, - args: &AbandonArgs, -) -> Result<(), CommandError> { - let mut workspace_command = command.workspace_helper(ui)?; - let to_abandon = resolve_multiple_nonempty_revsets(&args.revisions, &workspace_command, ui)?; - workspace_command.check_rewritable(to_abandon.iter())?; - let transaction_description = if to_abandon.len() == 1 { - format!("abandon commit {}", to_abandon[0].id().hex()) - } else { - format!( - "abandon commit {} and {} more", - to_abandon[0].id().hex(), - to_abandon.len() - 1 - ) - }; - let mut tx = workspace_command.start_transaction(&transaction_description); - for commit in &to_abandon { - tx.mut_repo().record_abandoned_commit(commit.id().clone()); - } - let num_rebased = tx.mut_repo().rebase_descendants(command.settings())?; - - if to_abandon.len() == 1 { - write!(ui.stderr(), "Abandoned commit ")?; - tx.base_workspace_helper() - .write_commit_summary(ui.stderr_formatter().as_mut(), &to_abandon[0])?; - writeln!(ui.stderr())?; - } else if !args.summary { - writeln!(ui.stderr(), "Abandoned the following commits:")?; - for commit in to_abandon { - write!(ui.stderr(), " ")?; - tx.base_workspace_helper() - .write_commit_summary(ui.stderr_formatter().as_mut(), &commit)?; - writeln!(ui.stderr())?; - } - } else { - writeln!(ui.stderr(), "Abandoned {} commits.", &to_abandon.len())?; - } - if num_rebased > 0 { - writeln!( - ui.stderr(), - "Rebased {num_rebased} descendant commits onto parents of abandoned commits" - )?; - } - tx.finish(ui)?; - Ok(()) -} - #[instrument(skip_all)] fn cmd_edit(ui: &mut Ui, command: &CommandHelper, args: &EditArgs) -> Result<(), CommandError> { let mut workspace_command = command.workspace_helper(ui)?; @@ -4065,7 +3998,7 @@ pub fn run_command(ui: &mut Ui, command_helper: &CommandHelper) -> Result<(), Co Commands::Describe(sub_args) => cmd_describe(ui, command_helper, sub_args), Commands::Commit(sub_args) => cmd_commit(ui, command_helper, sub_args), Commands::Duplicate(sub_args) => cmd_duplicate(ui, command_helper, sub_args), - Commands::Abandon(sub_args) => cmd_abandon(ui, command_helper, sub_args), + Commands::Abandon(sub_args) => abandon::cmd_abandon(ui, command_helper, sub_args), Commands::Edit(sub_args) => cmd_edit(ui, command_helper, sub_args), Commands::Next(sub_args) => cmd_next(ui, command_helper, sub_args), Commands::Prev(sub_args) => cmd_prev(ui, command_helper, sub_args),