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

Commands move chmod code to chmod rs #2444

Closed
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
91 changes: 91 additions & 0 deletions cli/src/commands/abandon.rs
Original file line number Diff line number Diff line change
@@ -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<RevisionArg>,
/// 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(())
}
61 changes: 61 additions & 0 deletions cli/src/commands/backout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// 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 jj_lib::backend::ObjectId;
use jj_lib::rewrite::back_out_commit;
use tracing::instrument;

use crate::cli_util::{CommandError, CommandHelper, RevisionArg};
use crate::ui::Ui;

/// Apply the reverse of a revision on top of another revision
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct BackoutArgs {
/// The revision to apply the reverse of
#[arg(long, short, default_value = "@")]
revision: RevisionArg,
/// The revision to apply the reverse changes on top of
// TODO: It seems better to default this to `@-`. Maybe the working
// copy should be rebased on top?
#[arg(long, short, default_value = "@")]
destination: Vec<RevisionArg>,
}

#[instrument(skip_all)]
pub(crate) fn cmd_backout(
ui: &mut Ui,
command: &CommandHelper,
args: &BackoutArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let commit_to_back_out = workspace_command.resolve_single_rev(&args.revision, ui)?;
let mut parents = vec![];
for revision_str in &args.destination {
let destination = workspace_command.resolve_single_rev(revision_str, ui)?;
parents.push(destination);
}
let mut tx = workspace_command.start_transaction(&format!(
"back out commit {}",
commit_to_back_out.id().hex()
));
back_out_commit(
command.settings(),
tx.mut_repo(),
&commit_to_back_out,
&parents,
)?;
tx.finish(ui)?;

Ok(())
}
75 changes: 75 additions & 0 deletions cli/src/commands/cat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// 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 futures::executor::block_on;
use tracing::instrument;

use jj_lib::{backend::TreeValue, conflicts, repo::Repo};

use crate::{
cli_util::{user_error, CommandError, CommandHelper, RevisionArg},
ui::Ui,
};

/// Print contents of a file in a revision
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct CatArgs {
/// The revision to get the file contents from
#[arg(long, short, default_value = "@")]
revision: RevisionArg,
/// The file to print
#[arg(value_hint = clap::ValueHint::FilePath)]
path: String,
}

#[instrument(skip_all)]
pub(crate) fn cmd_cat(
ui: &mut Ui,
command: &CommandHelper,
args: &CatArgs,
) -> Result<(), CommandError> {
let workspace_command = command.workspace_helper(ui)?;
let commit = workspace_command.resolve_single_rev(&args.revision, ui)?;
let tree = commit.tree()?;
let path = workspace_command.parse_file_path(&args.path)?;
let repo = workspace_command.repo();
match tree.path_value(&path).into_resolved() {
Ok(None) => {
return Err(user_error("No such path"));
}
Ok(Some(TreeValue::File { id, .. })) => {
let mut contents = repo.store().read_file(&path, &id)?;
ui.request_pager();
std::io::copy(&mut contents, &mut ui.stdout_formatter().as_mut())?;
}
Err(conflict) => {
let mut contents = vec![];
block_on(conflicts::materialize(
&conflict,
repo.store(),
&path,
&mut contents,
))
.unwrap();
ui.request_pager();
ui.stdout_formatter().write_all(&contents)?;
}
_ => {
return Err(user_error("Path exists but is not a file"));
}
}
Ok(())
}
63 changes: 63 additions & 0 deletions cli/src/commands/checkout.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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 tracing::instrument;

use jj_lib::backend::ObjectId;

use crate::{
cli_util::{join_message_paragraphs, CommandError, CommandHelper, RevisionArg},
ui::Ui,
};

/// Create a new, empty change and edit it in the working copy
///
/// For more information, see
/// https://github.com/martinvonz/jj/blob/main/docs/working-copy.md.
#[derive(clap::Args, Clone, Debug)]
#[command(visible_aliases = &["co"])]
pub(crate) struct CheckoutArgs {
/// The revision to update to
revision: RevisionArg,
/// Ignored (but lets you pass `-r` for consistency with other commands)
#[arg(short = 'r', hide = true)]
unused_revision: bool,
/// The change description to use
#[arg(long = "message", short, value_name = "MESSAGE")]
message_paragraphs: Vec<String>,
}

#[instrument(skip_all)]
pub(crate) fn cmd_checkout(
ui: &mut Ui,
command: &CommandHelper,
args: &CheckoutArgs,
) -> Result<(), CommandError> {
let mut workspace_command = command.workspace_helper(ui)?;
let target = workspace_command.resolve_single_rev(&args.revision, ui)?;
let mut tx =
workspace_command.start_transaction(&format!("check out commit {}", target.id().hex()));
let commit_builder = tx
.mut_repo()
.new_commit(
command.settings(),
vec![target.id().clone()],
target.tree_id().clone(),
)
.set_description(join_message_paragraphs(&args.message_paragraphs));
let new_commit = commit_builder.write()?;
tx.edit(&new_commit).unwrap();
tx.finish(ui)?;
Ok(())
}
Loading
Loading