ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: teach jj squash to move only changes to specified paths

This commit is contained in:
Martin von Zweigbergk 2022-04-09 10:27:17 -07:00 committed by Martin von Zweigbergk
parent 082ec5ae3b
commit 4be0da3607
3 changed files with 55 additions and 21 deletions

View file

@ -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

View file

@ -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,8 +3248,6 @@ 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!(
"\
You are moving changes from: {}
@ -3263,14 +3264,17 @@ 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)?;
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")));
}
} else {
new_parent_tree_id = commit.tree().id().clone();
}
// Abandon the child if the parent now has all the content from the child
// (always the case in the non-interactive case).
let abandon_child = &new_parent_tree_id == commit.tree().id();

View file

@ -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
");
}