Skip to content

Commit 89096e8

Browse files
feat(move): Add --fixup to squash moved commits into the destination
On disk squashes are more conflict prone than in memory.
1 parent 206aa3e commit 89096e8

File tree

4 files changed

+1692
-3
lines changed

4 files changed

+1692
-3
lines changed

git-branchless/src/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ fn do_main_and_drop_locals() -> eyre::Result<i32> {
223223
dest,
224224
base,
225225
exact,
226+
fixup,
226227
insert,
227228
move_options,
228229
} => r#move::r#move(
@@ -232,6 +233,7 @@ fn do_main_and_drop_locals() -> eyre::Result<i32> {
232233
dest,
233234
base,
234235
exact,
236+
fixup,
235237
insert,
236238
&move_options,
237239
)?,

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
@@ -311,6 +311,10 @@ pub enum Command {
311311
#[clap(value_parser, short = 'd', long = "dest")]
312312
dest: Option<Revset>,
313313

314+
/// Combine the moved commits and squash into the destination commit.
315+
#[clap(action, short = 'F', long = "fixup", conflicts_with = "insert")]
316+
fixup: bool,
317+
314318
/// Insert the subtree between the destination and it's children, if any.
315319
/// Only supported if the moved subtree has a single head.
316320
#[clap(action, short = 'I', long = "insert")]

0 commit comments

Comments
 (0)