Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: branch: split modules and do minor cleanup #3929

Merged
merged 7 commits into from
Jun 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
906 changes: 0 additions & 906 deletions cli/src/commands/branch.rs

This file was deleted.

78 changes: 78 additions & 0 deletions cli/src/commands/branch/create.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2020-2023 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::builder::NonEmptyStringValueParser;
use jj_lib::object_id::ObjectId as _;
use jj_lib::op_store::RefTarget;

use super::make_branch_term;
use crate::cli_util::{CommandHelper, RevisionArg};
use crate::command_error::{user_error_with_hint, CommandError};
use crate::ui::Ui;

/// Create a new branch
#[derive(clap::Args, Clone, Debug)]
pub struct BranchCreateArgs {
/// The branch's target revision
#[arg(long, short)]
revision: Option<RevisionArg>,

/// The branches to create
#[arg(required = true, value_parser = NonEmptyStringValueParser::new())]
names: Vec<String>,
}

pub fn cmd_branch_create(
ui: &mut Ui,
command: &CommandHelper,
args: &BranchCreateArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let target_commit =
workspace_command.resolve_single_rev(args.revision.as_ref().unwrap_or(&RevisionArg::AT))?;
let view = workspace_command.repo().view();
let branch_names = &args.names;
if let Some(branch_name) = branch_names
.iter()
.find(|&name| view.get_local_branch(name).is_present())
{
return Err(user_error_with_hint(
format!("Branch already exists: {branch_name}"),
"Use `jj branch set` to update it.",
));
}

if branch_names.len() > 1 {
writeln!(
ui.warning_default(),
"Creating multiple branches: {}",
branch_names.join(", "),
)?;
}

let mut tx = workspace_command.start_transaction();
for branch_name in branch_names {
tx.mut_repo()
.set_local_branch_target(branch_name, RefTarget::normal(target_commit.id().clone()));
}
tx.finish(
ui,
format!(
"create {} pointing to commit {}",
make_branch_term(branch_names),
target_commit.id().hex()
),
)?;
Ok(())
}
65 changes: 65 additions & 0 deletions cli/src/commands/branch/delete.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright 2020-2023 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 jj_lib::op_store::RefTarget;
use jj_lib::str_util::StringPattern;

use super::{find_local_branches, make_branch_term};
use crate::cli_util::CommandHelper;
use crate::command_error::CommandError;
use crate::ui::Ui;

/// Delete an existing branch and propagate the deletion to remotes on the
/// next push
#[derive(clap::Args, Clone, Debug)]
pub struct BranchDeleteArgs {
/// The branches to delete
///
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// select branches by wildcard pattern. For details, see
/// https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
#[arg(required_unless_present_any(&["glob"]), value_parser = StringPattern::parse)]
names: Vec<StringPattern>,

/// Deprecated. Please prefix the pattern with `glob:` instead.
#[arg(long, hide = true, value_parser = StringPattern::glob)]
glob: Vec<StringPattern>,
}

pub fn cmd_branch_delete(
ui: &mut Ui,
command: &CommandHelper,
args: &BranchDeleteArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let view = workspace_command.repo().view();
if !args.glob.is_empty() {
writeln!(
ui.warning_default(),
"--glob has been deprecated. Please prefix the pattern with `glob:` instead."
)?;
}
let name_patterns = [&args.names[..], &args.glob[..]].concat();
let names = find_local_branches(view, &name_patterns)?;
let mut tx = workspace_command.start_transaction();
for branch_name in names.iter() {
tx.mut_repo()
.set_local_branch_target(branch_name, RefTarget::absent());
}
tx.finish(ui, format!("delete {}", make_branch_term(&names)))?;
if names.len() > 1 {
writeln!(ui.status(), "Deleted {} branches.", names.len())?;
}
Ok(())
}
78 changes: 78 additions & 0 deletions cli/src/commands/branch/forget.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2020-2023 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 jj_lib::str_util::StringPattern;
use jj_lib::view::View;

use super::{find_branches_with, make_branch_term};
use crate::cli_util::CommandHelper;
use crate::command_error::CommandError;
use crate::ui::Ui;

/// Forget everything about a branch, including its local and remote
/// targets
///
/// A forgotten branch will not impact remotes on future pushes. It will be
/// recreated on future pulls if it still exists in the remote.
#[derive(clap::Args, Clone, Debug)]
pub struct BranchForgetArgs {
/// The branches to forget
///
/// By default, the specified name matches exactly. Use `glob:` prefix to
/// select branches by wildcard pattern. For details, see
/// https://github.com/martinvonz/jj/blob/main/docs/revsets.md#string-patterns.
#[arg(required_unless_present_any(&["glob"]), value_parser = StringPattern::parse)]
names: Vec<StringPattern>,

/// Deprecated. Please prefix the pattern with `glob:` instead.
#[arg(long, hide = true, value_parser = StringPattern::glob)]
glob: Vec<StringPattern>,
}

pub fn cmd_branch_forget(
ui: &mut Ui,
command: &CommandHelper,
args: &BranchForgetArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let view = workspace_command.repo().view();
if !args.glob.is_empty() {
writeln!(
ui.warning_default(),
"--glob has been deprecated. Please prefix the pattern with `glob:` instead."
)?;
}
let name_patterns = [&args.names[..], &args.glob[..]].concat();
let names = find_forgettable_branches(view, &name_patterns)?;
let mut tx = workspace_command.start_transaction();
for branch_name in names.iter() {
tx.mut_repo().remove_branch(branch_name);
}
tx.finish(ui, format!("forget {}", make_branch_term(&names)))?;
if names.len() > 1 {
writeln!(ui.status(), "Forgot {} branches.", names.len())?;
}
Ok(())
}

fn find_forgettable_branches(
view: &View,
name_patterns: &[StringPattern],
) -> Result<Vec<String>, CommandError> {
find_branches_with(name_patterns, |pattern| {
view.branches()
.filter(|(name, _)| pattern.matches(name))
.map(|(name, _)| name.to_owned())
})
}
Loading