From abe658d966ff282e2540e99bb7641efb8c05bb9e Mon Sep 17 00:00:00 2001 From: Antoine Cezar Date: Thu, 2 Nov 2023 20:30:16 +0100 Subject: [PATCH] commands: move status code to status.rs --- cli/src/commands/mod.rs | 117 +------------------------------ cli/src/commands/status.rs | 136 +++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 114 deletions(-) create mode 100644 cli/src/commands/status.rs diff --git a/cli/src/commands/mod.rs b/cli/src/commands/mod.rs index 59997dd8b..324652bf7 100644 --- a/cli/src/commands/mod.rs +++ b/cli/src/commands/mod.rs @@ -48,6 +48,7 @@ mod show; mod sparse; mod split; mod squash; +mod status; use std::fmt::Debug; use std::io::Write; @@ -136,7 +137,7 @@ enum Commands { Sparse(sparse::SparseArgs), Split(split::SplitArgs), Squash(squash::SquashArgs), - Status(StatusArgs), + Status(status::StatusArgs), #[command(subcommand)] Util(UtilCommands), /// Undo an operation (shortcut for `jj op undo`) @@ -160,18 +161,6 @@ struct UntrackArgs { paths: Vec, } -/// Show high-level repo status -/// -/// This includes: -/// -/// * The working copy commit and its (first) parent, and a summary of the -/// changes between them -/// -/// * Conflicted branches (see https://github.com/martinvonz/jj/blob/main/docs/branches.md) -#[derive(clap::Args, Clone, Debug)] -#[command(visible_alias = "st")] -struct StatusArgs {} - /// Move changes from a revision's parent into the revision /// /// After moving the changes out of the parent, the child revision will have the @@ -382,106 +371,6 @@ Make sure they're ignored, then try again.", Ok(()) } -#[instrument(skip_all)] -fn cmd_status( - ui: &mut Ui, - command: &CommandHelper, - _args: &StatusArgs, -) -> Result<(), CommandError> { - let workspace_command = command.workspace_helper(ui)?; - let repo = workspace_command.repo(); - let maybe_wc_commit = workspace_command - .get_wc_commit_id() - .map(|id| repo.store().get_commit(id)) - .transpose()?; - ui.request_pager(); - let mut formatter = ui.stdout_formatter(); - let formatter = formatter.as_mut(); - - if let Some(wc_commit) = &maybe_wc_commit { - let parent_tree = merge_commit_trees(repo.as_ref(), &wc_commit.parents())?; - let tree = wc_commit.tree()?; - if tree.id() == parent_tree.id() { - formatter.write_str("The working copy is clean\n")?; - } else { - formatter.write_str("Working copy changes:\n")?; - diff_util::show_diff_summary( - formatter, - &workspace_command, - parent_tree.diff(&tree, &EverythingMatcher), - )?; - } - - let conflicts = wc_commit.tree()?.conflicts().collect_vec(); - if !conflicts.is_empty() { - writeln!( - formatter.labeled("conflict"), - "There are unresolved conflicts at these paths:" - )?; - resolve::print_conflicted_paths(&conflicts, formatter, &workspace_command)? - } - - formatter.write_str("Working copy : ")?; - formatter.with_label("working_copy", |fmt| { - workspace_command.write_commit_summary(fmt, wc_commit) - })?; - formatter.write_str("\n")?; - for parent in wc_commit.parents() { - formatter.write_str("Parent commit: ")?; - workspace_command.write_commit_summary(formatter, &parent)?; - formatter.write_str("\n")?; - } - } else { - formatter.write_str("No working copy\n")?; - } - - let conflicted_local_branches = repo - .view() - .local_branches() - .filter(|(_, target)| target.has_conflict()) - .map(|(branch_name, _)| branch_name) - .collect_vec(); - let conflicted_remote_branches = repo - .view() - .all_remote_branches() - .filter(|(_, remote_ref)| remote_ref.target.has_conflict()) - .map(|(full_name, _)| full_name) - .collect_vec(); - if !conflicted_local_branches.is_empty() { - writeln!( - formatter.labeled("conflict"), - "These branches have conflicts:" - )?; - for branch_name in conflicted_local_branches { - write!(formatter, " ")?; - write!(formatter.labeled("branch"), "{branch_name}")?; - writeln!(formatter)?; - } - writeln!( - formatter, - " Use `jj branch list` to see details. Use `jj branch set -r ` to \ - resolve." - )?; - } - if !conflicted_remote_branches.is_empty() { - writeln!( - formatter.labeled("conflict"), - "These remote branches have conflicts:" - )?; - for (branch_name, remote_name) in conflicted_remote_branches { - write!(formatter, " ")?; - write!(formatter.labeled("branch"), "{branch_name}@{remote_name}")?; - writeln!(formatter)?; - } - writeln!( - formatter, - " Use `jj branch list` to see details. Use `jj git fetch` to resolve." - )?; - } - - Ok(()) -} - fn show_predecessor_patch( ui: &Ui, formatter: &mut dyn Formatter, @@ -1008,7 +897,7 @@ pub fn run_command(ui: &mut Ui, command_helper: &CommandHelper) -> Result<(), Co Commands::Cat(sub_args) => cat::cmd_cat(ui, command_helper, sub_args), Commands::Diff(sub_args) => diff::cmd_diff(ui, command_helper, sub_args), Commands::Show(sub_args) => show::cmd_show(ui, command_helper, sub_args), - Commands::Status(sub_args) => cmd_status(ui, command_helper, sub_args), + Commands::Status(sub_args) => status::cmd_status(ui, command_helper, sub_args), Commands::Log(sub_args) => log::cmd_log(ui, command_helper, sub_args), Commands::Interdiff(sub_args) => interdiff::cmd_interdiff(ui, command_helper, sub_args), Commands::Obslog(sub_args) => obslog::cmd_obslog(ui, command_helper, sub_args), diff --git a/cli/src/commands/status.rs b/cli/src/commands/status.rs new file mode 100644 index 000000000..64892465b --- /dev/null +++ b/cli/src/commands/status.rs @@ -0,0 +1,136 @@ +// 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 itertools::Itertools; +use jj_lib::matchers::EverythingMatcher; +use jj_lib::repo::Repo; +use jj_lib::rewrite::merge_commit_trees; +use tracing::instrument; + +use super::resolve; +use crate::cli_util::{CommandError, CommandHelper}; +use crate::diff_util; +use crate::ui::Ui; + +/// Show high-level repo status +/// +/// This includes: +/// +/// * The working copy commit and its (first) parent, and a summary of the +/// changes between them +/// +/// * Conflicted branches (see https://github.com/martinvonz/jj/blob/main/docs/branches.md) +#[derive(clap::Args, Clone, Debug)] +#[command(visible_alias = "st")] +pub(crate) struct StatusArgs {} + +#[instrument(skip_all)] +pub(crate) fn cmd_status( + ui: &mut Ui, + command: &CommandHelper, + _args: &StatusArgs, +) -> Result<(), CommandError> { + let workspace_command = command.workspace_helper(ui)?; + let repo = workspace_command.repo(); + let maybe_wc_commit = workspace_command + .get_wc_commit_id() + .map(|id| repo.store().get_commit(id)) + .transpose()?; + ui.request_pager(); + let mut formatter = ui.stdout_formatter(); + let formatter = formatter.as_mut(); + + if let Some(wc_commit) = &maybe_wc_commit { + let parent_tree = merge_commit_trees(repo.as_ref(), &wc_commit.parents())?; + let tree = wc_commit.tree()?; + if tree.id() == parent_tree.id() { + formatter.write_str("The working copy is clean\n")?; + } else { + formatter.write_str("Working copy changes:\n")?; + diff_util::show_diff_summary( + formatter, + &workspace_command, + parent_tree.diff(&tree, &EverythingMatcher), + )?; + } + + let conflicts = wc_commit.tree()?.conflicts().collect_vec(); + if !conflicts.is_empty() { + writeln!( + formatter.labeled("conflict"), + "There are unresolved conflicts at these paths:" + )?; + resolve::print_conflicted_paths(&conflicts, formatter, &workspace_command)? + } + + formatter.write_str("Working copy : ")?; + formatter.with_label("working_copy", |fmt| { + workspace_command.write_commit_summary(fmt, wc_commit) + })?; + formatter.write_str("\n")?; + for parent in wc_commit.parents() { + formatter.write_str("Parent commit: ")?; + workspace_command.write_commit_summary(formatter, &parent)?; + formatter.write_str("\n")?; + } + } else { + formatter.write_str("No working copy\n")?; + } + + let conflicted_local_branches = repo + .view() + .local_branches() + .filter(|(_, target)| target.has_conflict()) + .map(|(branch_name, _)| branch_name) + .collect_vec(); + let conflicted_remote_branches = repo + .view() + .all_remote_branches() + .filter(|(_, remote_ref)| remote_ref.target.has_conflict()) + .map(|(full_name, _)| full_name) + .collect_vec(); + if !conflicted_local_branches.is_empty() { + writeln!( + formatter.labeled("conflict"), + "These branches have conflicts:" + )?; + for branch_name in conflicted_local_branches { + write!(formatter, " ")?; + write!(formatter.labeled("branch"), "{branch_name}")?; + writeln!(formatter)?; + } + writeln!( + formatter, + " Use `jj branch list` to see details. Use `jj branch set -r ` to \ + resolve." + )?; + } + if !conflicted_remote_branches.is_empty() { + writeln!( + formatter.labeled("conflict"), + "These remote branches have conflicts:" + )?; + for (branch_name, remote_name) in conflicted_remote_branches { + write!(formatter, " ")?; + write!(formatter.labeled("branch"), "{branch_name}@{remote_name}")?; + writeln!(formatter)?; + } + writeln!( + formatter, + " Use `jj branch list` to see details. Use `jj git fetch` to resolve." + )?; + } + + Ok(()) +}