Skip to content

Commit 283a368

Browse files
feat(move): Add --fixup to squash moved commits into the destination
1 parent dfe0e08 commit 283a368

File tree

5 files changed

+939
-3
lines changed

5 files changed

+939
-3
lines changed

git-branchless-lib/src/core/rewrite/execute.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,10 @@ mod in_memory {
582582
"Applying patch for commit: {}",
583583
fixup_commit_description
584584
));
585+
// TODO it's possible that we could skip much of this
586+
// loop if, instead of creating a commit and then
587+
// immediately (repeatedly) amending and re-creating it,
588+
// we just amended the tree and then commited it once
585589
let commit_tree = repo.amend_fast(
586590
&rebased_commit,
587591
&AmendFastOptions::FromCommit {

git-branchless/src/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ fn do_main_and_drop_locals() -> eyre::Result<i32> {
211211
dest,
212212
base,
213213
exact,
214+
fixup,
214215
insert,
215216
move_options,
216217
} => r#move::r#move(
@@ -220,6 +221,7 @@ fn do_main_and_drop_locals() -> eyre::Result<i32> {
220221
dest,
221222
base,
222223
exact,
224+
fixup,
223225
insert,
224226
&move_options,
225227
)?,

git-branchless/src/commands/move.rs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ pub fn r#move(
6464
dest: Option<Revset>,
6565
bases: Vec<Revset>,
6666
exacts: Vec<Revset>,
67+
fixup: bool,
6768
insert: bool,
6869
move_options: &MoveOptions,
6970
) -> eyre::Result<ExitCode> {
@@ -255,7 +256,7 @@ pub fn r#move(
255256
let commits_to_move = commits_to_move.union(&union_all(
256257
&exact_components.values().cloned().collect::<Vec<_>>(),
257258
));
258-
let commits_to_move = if insert {
259+
let commits_to_move = if insert || fixup {
259260
commits_to_move.union(&dag.query().children(CommitSet::from(dest_oid))?)
260261
} else {
261262
commits_to_move
@@ -274,7 +275,18 @@ pub fn r#move(
274275

275276
let source_roots = dag.query().roots(source_oids.clone())?;
276277
for source_root in commit_set_to_vec(&source_roots)? {
277-
builder.move_subtree(source_root, vec![dest_oid])?;
278+
if fixup {
279+
let commits = dag
280+
.query()
281+
.descendants(CommitSet::from(source_root))?
282+
.difference(&dag.obsolete_commits);
283+
let commits = commit_set_to_vec(&commits)?;
284+
for commit in commits.iter() {
285+
builder.fixup_commit(*commit, dest_oid)?;
286+
}
287+
} else {
288+
builder.move_subtree(source_root, vec![dest_oid])?;
289+
}
278290
}
279291

280292
let component_roots: CommitSet = exact_components.keys().cloned().collect();
@@ -383,7 +395,14 @@ pub fn r#move(
383395
}
384396
}
385397

386-
builder.move_subtree(component_root, vec![component_dest_oid])?;
398+
if fixup {
399+
let commits = commit_set_to_vec(component)?;
400+
for commit in commits.iter() {
401+
builder.fixup_commit(*commit, dest_oid)?;
402+
}
403+
} else {
404+
builder.move_subtree(component_root, vec![component_dest_oid])?;
405+
}
387406
}
388407

389408
if insert {

git-branchless/src/opts.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,10 @@ pub enum Command {
319319
#[clap(value_parser, short = 'd', long = "dest")]
320320
dest: Option<Revset>,
321321

322+
/// Combine the moved commits and squash into the destination commit.
323+
#[clap(action, short = 'F', long = "fixup", conflicts_with = "insert")]
324+
fixup: bool,
325+
322326
/// Insert the subtree between the destination and it's children, if any.
323327
/// Only supported if the moved subtree has a single head.
324328
#[clap(action, short = 'I', long = "insert")]

0 commit comments

Comments
 (0)