mirror of
https://github.com/martinvonz/jj.git
synced 2024-09-11 05:45:30 +03:00
cmd: Add --to
and --from
arguments to jj touchup
This allows touching up a commit while seeing the differences between it and another arbitrary commit.
This commit is contained in:
parent
b474fc6ab5
commit
f71ca25ebe
@ -537,19 +537,34 @@ struct RestoreArgs {
|
||||
paths: Vec<String>,
|
||||
}
|
||||
|
||||
/// Touch up the content changes in a revision
|
||||
/// Touch up the content changes in a revision with a diff editor
|
||||
///
|
||||
/// With the `-r` option, which is the default, starts a diff editor (`meld` by
|
||||
/// default) on the changes in the revision.
|
||||
///
|
||||
/// With the `--from` and/or `--to` options, starts a diff editor comparing the
|
||||
/// "from" revision to the "to" revision.
|
||||
///
|
||||
/// Starts a diff editor (`meld` by default) on the changes in the revision.
|
||||
/// Edit the right side of the diff until it looks the way you want. Once you
|
||||
/// close the editor, the revision will be updated. Descendants will be rebased
|
||||
/// on top as usual, which may result in conflicts. See `jj squash -i` or `jj
|
||||
/// unsquash -i` if you instead want to move changes into or out of the parent
|
||||
/// revision.
|
||||
/// close the editor, the revision specified with `-r` or `--to` will be
|
||||
/// updated. Descendants will be rebased on top as usual, which may result in
|
||||
/// conflicts.
|
||||
///
|
||||
/// See `jj restore` if you want to move entire files from one revision to
|
||||
/// another. See `jj squash -i` or `jj unsquash -i` if you instead want to move
|
||||
/// changes into or out of the parent revision.
|
||||
#[derive(clap::Args, Clone, Debug)]
|
||||
struct TouchupArgs {
|
||||
/// The revision to touch up
|
||||
#[arg(long, short, default_value = "@")]
|
||||
revision: RevisionArg,
|
||||
/// The revision to touch up. Defaults to @ if --to/--from are not
|
||||
/// specified.
|
||||
#[arg(long, short)]
|
||||
revision: Option<RevisionArg>,
|
||||
/// Show changes from this revision. Defaults to @ if --to is specified.
|
||||
#[arg(long, conflicts_with = "revision")]
|
||||
from: Option<RevisionArg>,
|
||||
/// Edit changes in this revision. Defaults to @ if --from is specified.
|
||||
#[arg(long, conflicts_with = "revision")]
|
||||
to: Option<RevisionArg>,
|
||||
}
|
||||
|
||||
/// Split a revision in two
|
||||
@ -2408,27 +2423,47 @@ fn cmd_touchup(
|
||||
args: &TouchupArgs,
|
||||
) -> Result<(), CommandError> {
|
||||
let mut workspace_command = command.workspace_helper(ui)?;
|
||||
let commit = workspace_command.resolve_single_rev(&args.revision)?;
|
||||
workspace_command.check_rewriteable(&commit)?;
|
||||
let base_tree = merge_commit_trees(workspace_command.repo().as_repo_ref(), &commit.parents());
|
||||
|
||||
let (target_commit, base_commits, diff_description);
|
||||
if args.from.is_some() || args.to.is_some() {
|
||||
target_commit = workspace_command.resolve_single_rev(args.to.as_deref().unwrap_or("@"))?;
|
||||
base_commits =
|
||||
vec![workspace_command.resolve_single_rev(args.from.as_deref().unwrap_or("@"))?];
|
||||
diff_description = format!(
|
||||
"The diff initially shows the commit's changes relative to:\n{}",
|
||||
short_commit_description(&base_commits[0])
|
||||
);
|
||||
} else {
|
||||
target_commit =
|
||||
workspace_command.resolve_single_rev(args.revision.as_deref().unwrap_or("@"))?;
|
||||
base_commits = target_commit.parents();
|
||||
diff_description = "The diff initially shows the commit's changes.".to_string();
|
||||
};
|
||||
workspace_command.check_rewriteable(&target_commit)?;
|
||||
|
||||
let instructions = format!(
|
||||
"\
|
||||
You are editing changes in: {}
|
||||
|
||||
The diff initially shows the commit's changes.
|
||||
{diff_description}
|
||||
|
||||
Adjust the right side until it shows the contents you want. If you
|
||||
don't make any changes, then the operation will be aborted.",
|
||||
short_commit_description(&commit)
|
||||
short_commit_description(&target_commit),
|
||||
);
|
||||
let tree_id = workspace_command.edit_diff(ui, &base_tree, &commit.tree(), &instructions)?;
|
||||
if &tree_id == commit.tree_id() {
|
||||
let base_tree = merge_commit_trees(
|
||||
workspace_command.repo().as_repo_ref(),
|
||||
base_commits.as_slice(),
|
||||
);
|
||||
let tree_id =
|
||||
workspace_command.edit_diff(ui, &base_tree, &target_commit.tree(), &instructions)?;
|
||||
if &tree_id == target_commit.tree_id() {
|
||||
ui.write("Nothing changed.\n")?;
|
||||
} else {
|
||||
let mut tx =
|
||||
workspace_command.start_transaction(&format!("edit commit {}", commit.id().hex()));
|
||||
let mut tx = workspace_command
|
||||
.start_transaction(&format!("edit commit {}", target_commit.id().hex()));
|
||||
let mut_repo = tx.mut_repo();
|
||||
let new_commit = CommitBuilder::for_rewrite_from(ui.settings(), &commit)
|
||||
let new_commit = CommitBuilder::for_rewrite_from(ui.settings(), &target_commit)
|
||||
.set_tree(tree_id)
|
||||
.write_to_repo(mut_repo);
|
||||
ui.write("Created ")?;
|
||||
|
@ -263,12 +263,14 @@ fn test_help() {
|
||||
|
||||
let stdout = test_env.jj_cmd_success(test_env.env_root(), &["touchup", "-h"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Touch up the content changes in a revision
|
||||
Touch up the content changes in a revision with a diff editor
|
||||
|
||||
Usage: jj touchup [OPTIONS]
|
||||
|
||||
Options:
|
||||
-r, --revision <REVISION> The revision to touch up [default: @]
|
||||
-r, --revision <REVISION> The revision to touch up. Defaults to @ if --to/--from are not specified
|
||||
--from <FROM> Show changes from this revision. Defaults to @ if --to is specified
|
||||
--to <TO> Edit changes in this revision. Defaults to @ if --from is specified
|
||||
-h, --help Print help information (use `--help` for more detail)
|
||||
|
||||
Global Options:
|
||||
|
@ -25,6 +25,7 @@ fn test_touchup() {
|
||||
let repo_path = test_env.env_root().join("repo");
|
||||
|
||||
std::fs::write(repo_path.join("file1"), "a\n").unwrap();
|
||||
test_env.jj_cmd_success(&repo_path, &["new"]);
|
||||
std::fs::write(repo_path.join("file2"), "a\n").unwrap();
|
||||
std::fs::write(repo_path.join("file3"), "a\n").unwrap();
|
||||
test_env.jj_cmd_success(&repo_path, &["new"]);
|
||||
@ -66,8 +67,8 @@ fn test_touchup() {
|
||||
std::fs::write(&edit_script, "reset file2").unwrap();
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["touchup"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Created 8c79910b5033 (no description set)
|
||||
Working copy now at: 8c79910b5033 (no description set)
|
||||
Created 1930da4a57e9 (no description set)
|
||||
Working copy now at: 1930da4a57e9 (no description set)
|
||||
Added 0 files, modified 1 files, removed 0 files
|
||||
"###);
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
|
||||
@ -80,15 +81,34 @@ fn test_touchup() {
|
||||
std::fs::write(&edit_script, "write file3\nmodified\n").unwrap();
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["touchup", "-r", "@-"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Created 472de2debaff (no description set)
|
||||
Created c03ae96780b6 (no description set)
|
||||
Rebased 1 descendant commits
|
||||
Working copy now at: 6d19dc1ea106 (no description set)
|
||||
Working copy now at: 2a4dc204a6ab (no description set)
|
||||
Added 0 files, modified 1 files, removed 0 files
|
||||
"###);
|
||||
let contents = String::from_utf8(std::fs::read(repo_path.join("file3")).unwrap()).unwrap();
|
||||
insta::assert_snapshot!(contents, @r###"
|
||||
modified
|
||||
"###);
|
||||
|
||||
// Test touchup --from @--
|
||||
test_env.jj_cmd_success(&repo_path, &["undo"]);
|
||||
std::fs::write(
|
||||
&edit_script,
|
||||
"files-before file1\0files-after JJ-INSTRUCTIONS file2 file3\0reset file2",
|
||||
)
|
||||
.unwrap();
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["touchup", "--from", "@--"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Created 15f2c966d508 (no description set)
|
||||
Working copy now at: 15f2c966d508 (no description set)
|
||||
Added 0 files, modified 0 files, removed 1 files
|
||||
"###);
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
R file1
|
||||
R file2
|
||||
"###);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
Loading…
Reference in New Issue
Block a user