mirror of
https://github.com/martinvonz/jj.git
synced 2024-11-10 14:16:24 +03:00
cli: teach jj squash
to move only changes to specified paths
This commit is contained in:
parent
082ec5ae3b
commit
4be0da3607
@ -11,10 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
* The new `jj print` command prints the contents of a file in a revision.
|
||||
|
||||
* `jj move` now lets you limit the set of changes to move by specifying paths
|
||||
on the command line (in addition to the `--interactive` mode). For example,
|
||||
use `jj move --to @-- foo` to move the changes to file (or directory) `foo` in
|
||||
the working copy to the grandparent commit.
|
||||
* `jj move` and `jj squash` now lets you limit the set of changes to move by
|
||||
specifying paths on the command line (in addition to the `--interactive`
|
||||
mode). For example, use `jj move --to @-- foo` to move the changes to file
|
||||
(or directory) `foo` in the working copy to the grandparent commit.
|
||||
|
||||
### Fixed bugs
|
||||
|
||||
|
@ -1292,6 +1292,9 @@ struct SquashArgs {
|
||||
/// Interactively choose which parts to squash
|
||||
#[clap(long, short)]
|
||||
interactive: bool,
|
||||
/// Move only changes to these paths (instead of all paths)
|
||||
#[clap(conflicts_with = "interactive")]
|
||||
paths: Vec<String>,
|
||||
}
|
||||
|
||||
/// Move changes from a revision's parent into the revision
|
||||
@ -3245,10 +3248,8 @@ fn cmd_squash(ui: &mut Ui, command: &CommandHelper, args: &SquashArgs) -> Result
|
||||
let mut tx =
|
||||
workspace_command.start_transaction(&format!("squash commit {}", commit.id().hex()));
|
||||
let mut_repo = tx.mut_repo();
|
||||
let new_parent_tree_id;
|
||||
if args.interactive {
|
||||
let instructions = format!(
|
||||
"\
|
||||
let instructions = format!(
|
||||
"\
|
||||
You are moving changes from: {}
|
||||
into its parent: {}
|
||||
|
||||
@ -3260,16 +3261,19 @@ Adjust the right side until the diff shows the changes you want to move
|
||||
to the destination. If you don't make any changes, then all the changes
|
||||
from the source will be moved into the parent.
|
||||
",
|
||||
short_commit_description(&commit),
|
||||
short_commit_description(parent)
|
||||
);
|
||||
new_parent_tree_id =
|
||||
workspace_command.edit_diff(&parent.tree(), &commit.tree(), &instructions)?;
|
||||
if &new_parent_tree_id == parent.tree().id() {
|
||||
return Err(CommandError::UserError(String::from("No changes selected")));
|
||||
}
|
||||
} else {
|
||||
new_parent_tree_id = commit.tree().id().clone();
|
||||
short_commit_description(&commit),
|
||||
short_commit_description(parent)
|
||||
);
|
||||
let new_parent_tree_id = workspace_command.select_diff(
|
||||
ui,
|
||||
&parent.tree(),
|
||||
&commit.tree(),
|
||||
&instructions,
|
||||
args.interactive,
|
||||
&args.paths,
|
||||
)?;
|
||||
if &new_parent_tree_id == parent.tree().id() {
|
||||
return Err(CommandError::UserError(String::from("No changes selected")));
|
||||
}
|
||||
// Abandon the child if the parent now has all the content from the child
|
||||
// (always the case in the non-interactive case).
|
||||
|
@ -122,7 +122,7 @@ fn test_squash() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_squash_interactive() {
|
||||
fn test_squash_partial() {
|
||||
let mut test_env = TestEnvironment::default();
|
||||
test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]);
|
||||
let repo_path = test_env.env_root().join("repo");
|
||||
@ -148,7 +148,8 @@ fn test_squash_interactive() {
|
||||
o 000000000000
|
||||
"###);
|
||||
|
||||
// Everything is moved into the parent if no change is made
|
||||
// If we don't make any changes in the diff-editor, the whole change is moved
|
||||
// into the parent
|
||||
let edit_script = test_env.set_up_fake_diff_editor();
|
||||
std::fs::write(&edit_script, "").unwrap();
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["squash", "-r", "b", "-i"]);
|
||||
@ -166,7 +167,7 @@ fn test_squash_interactive() {
|
||||
insta::assert_snapshot!(stdout, @"b
|
||||
");
|
||||
|
||||
// Can squash only some changes
|
||||
// Can squash only some changes in interactive mode
|
||||
test_env.jj_cmd_success(&repo_path, &["undo"]);
|
||||
std::fs::write(&edit_script, "reset file1").unwrap();
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["squash", "-r", "b", "-i"]);
|
||||
@ -193,4 +194,33 @@ fn test_squash_interactive() {
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["print", "file2", "-r", "b"]);
|
||||
insta::assert_snapshot!(stdout, @"b
|
||||
");
|
||||
|
||||
// Can squash only some changes in non-interactive mode
|
||||
test_env.jj_cmd_success(&repo_path, &["undo"]);
|
||||
// Clear the script so we know it won't be used even without -i
|
||||
std::fs::write(&edit_script, "").unwrap();
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["squash", "-r", "b", "file2"]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
Rebased 1 descendant commits
|
||||
Working copy now at: a911fa1d0627
|
||||
"###);
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", template]);
|
||||
insta::assert_snapshot!(stdout, @r###"
|
||||
@ a911fa1d0627 c
|
||||
o fb73ad17899f b
|
||||
o 70621f4c7a42 a
|
||||
o 000000000000
|
||||
"###);
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["print", "file1", "-r", "a"]);
|
||||
insta::assert_snapshot!(stdout, @"a
|
||||
");
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["print", "file2", "-r", "a"]);
|
||||
insta::assert_snapshot!(stdout, @"b
|
||||
");
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["print", "file1", "-r", "b"]);
|
||||
insta::assert_snapshot!(stdout, @"b
|
||||
");
|
||||
let stdout = test_env.jj_cmd_success(&repo_path, &["print", "file2", "-r", "b"]);
|
||||
insta::assert_snapshot!(stdout, @"b
|
||||
");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user