forked from mirrors/jj
squash: add --interactive for moving only part a commit into its parent
This commit is contained in:
parent
7e4e43f358
commit
8502aaffd1
1 changed files with 20 additions and 9 deletions
|
@ -360,8 +360,9 @@ fn get_app<'a, 'b>() -> App<'a, 'b> {
|
|||
.about("create a new, empty commit")
|
||||
.arg(rev_arg());
|
||||
let squash_command = SubCommand::with_name("squash")
|
||||
.about("squash a commit into its parent")
|
||||
.arg(rev_arg());
|
||||
.about("move changes from a commit into its parent")
|
||||
.arg(rev_arg())
|
||||
.arg(Arg::with_name("interactive").long("interactive").short("i"));
|
||||
let discard_command = SubCommand::with_name("discard")
|
||||
.about("discard a commit (and its descendants)")
|
||||
.arg(rev_arg());
|
||||
|
@ -1384,16 +1385,26 @@ fn cmd_squash(
|
|||
}
|
||||
let mut tx = repo.start_transaction(&format!("squash commit {}", commit.id().hex()));
|
||||
let mut_repo = tx.mut_repo();
|
||||
let squashed_commit = CommitBuilder::for_rewrite_from(ui.settings(), repo.store(), &parent)
|
||||
.set_tree(commit.tree().id().clone())
|
||||
let new_parent_tree_id;
|
||||
if sub_matches.is_present("interactive") {
|
||||
new_parent_tree_id = crate::diff_edit::edit_diff(&parent.tree(), &commit.tree())?;
|
||||
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();
|
||||
}
|
||||
// Prune the child if the parent now has all the content from the child (always
|
||||
// the case in the non-interactive case).
|
||||
let prune_child = &new_parent_tree_id == commit.tree().id();
|
||||
let new_parent = CommitBuilder::for_rewrite_from(ui.settings(), repo.store(), &parent)
|
||||
.set_tree(new_parent_tree_id)
|
||||
.set_predecessors(vec![parent.id().clone(), commit.id().clone()])
|
||||
.write_to_repo(mut_repo);
|
||||
// Commit the remainder on top of the new commit (always empty in the
|
||||
// non-interactive case), so the squashed-in commit becomes obsolete, and so
|
||||
// descendants evolve correctly.
|
||||
// Commit the remainder on top of the new parent commit.
|
||||
CommitBuilder::for_rewrite_from(ui.settings(), repo.store(), &commit)
|
||||
.set_parents(vec![squashed_commit.id().clone()])
|
||||
.set_pruned(true)
|
||||
.set_parents(vec![new_parent.id().clone()])
|
||||
.set_pruned(prune_child)
|
||||
.write_to_repo(mut_repo);
|
||||
update_checkout_after_rewrite(ui, mut_repo);
|
||||
tx.commit();
|
||||
|
|
Loading…
Reference in a new issue