Skip to content

Commit 3ad2f74

Browse files
feat(move): Add --fixup to squash moved commits into the destination
This only implements in-memory rebases/fixups. On-disk rebases can come later.
1 parent 7ab4cdd commit 3ad2f74

File tree

4 files changed

+1396
-3
lines changed

4 files changed

+1396
-3
lines changed

git-branchless-move/src/lib.rs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ pub fn r#move(
7373
exacts: Vec<Revset>,
7474
resolve_revset_options: &ResolveRevsetOptions,
7575
move_options: &MoveOptions,
76+
fixup: bool,
7677
insert: bool,
7778
) -> EyreExitOr<()> {
7879
let sources_provided = !sources.is_empty();
@@ -278,7 +279,7 @@ pub fn r#move(
278279
let commits_to_move = commits_to_move.union(&union_all(
279280
&exact_components.values().cloned().collect::<Vec<_>>(),
280281
));
281-
let commits_to_move = if insert {
282+
let commits_to_move = if insert || fixup {
282283
commits_to_move.union(&dag.query_children(CommitSet::from(dest_oid))?)
283284
} else {
284285
commits_to_move
@@ -297,7 +298,15 @@ pub fn r#move(
297298

298299
let source_roots = dag.query_roots(source_oids.clone())?;
299300
for source_root in dag.commit_set_to_vec(&source_roots)? {
300-
builder.move_subtree(source_root, vec![dest_oid])?;
301+
if fixup {
302+
let commits = dag.query_descendants(CommitSet::from(source_root))?;
303+
let commits = dag.commit_set_to_vec(&commits)?;
304+
for commit in commits.iter() {
305+
builder.fixup_commit(*commit, dest_oid)?;
306+
}
307+
} else {
308+
builder.move_subtree(source_root, vec![dest_oid])?;
309+
}
301310
}
302311

303312
let component_roots: CommitSet = exact_components.keys().cloned().collect();
@@ -394,7 +403,14 @@ pub fn r#move(
394403
}
395404
}
396405

397-
builder.move_subtree(component_root, vec![component_dest_oid])?;
406+
if fixup {
407+
let commits = dag.commit_set_to_vec(component)?;
408+
for commit in commits.iter() {
409+
builder.fixup_commit(*commit, dest_oid)?;
410+
}
411+
} else {
412+
builder.move_subtree(component_root, vec![component_dest_oid])?;
413+
}
398414
}
399415

400416
if insert {

git-branchless-opts/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,10 @@ pub enum Command {
513513
#[clap(flatten)]
514514
move_options: MoveOptions,
515515

516+
/// Combine the moved commits and squash them into the destination commit.
517+
#[clap(action, short = 'F', long = "fixup", conflicts_with = "insert")]
518+
fixup: bool,
519+
516520
/// Insert the subtree between the destination and it's children, if any.
517521
/// Only supported if the moved subtree has a single head.
518522
#[clap(action, short = 'I', long = "insert")]

git-branchless/src/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ fn command_main(ctx: CommandContext, opts: Opts) -> EyreExitOr<()> {
9393
exact,
9494
resolve_revset_options,
9595
move_options,
96+
fixup,
9697
insert,
9798
} => git_branchless_move::r#move(
9899
&effects,
@@ -103,6 +104,7 @@ fn command_main(ctx: CommandContext, opts: Opts) -> EyreExitOr<()> {
103104
exact,
104105
&resolve_revset_options,
105106
&move_options,
107+
fixup,
106108
insert,
107109
)?,
108110

0 commit comments

Comments
 (0)