Skip to content

Commit dfe0e08

Browse files
feat(rebase): Update RebaseCommand::Pick to support squashing commits
1 parent efc3c35 commit dfe0e08

File tree

2 files changed

+262
-56
lines changed

2 files changed

+262
-56
lines changed

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

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,8 @@ mod in_memory {
354354
use crate::core::rewrite::move_branches;
355355
use crate::core::rewrite::plan::{OidOrLabel, RebaseCommand, RebasePlan};
356356
use crate::git::{
357-
CherryPickFastError, CherryPickFastOptions, GitRunInfo, MaybeZeroOid, NonZeroOid, Repo,
357+
AmendFastOptions, CherryPickFastError, CherryPickFastOptions, GitRunInfo, MaybeZeroOid,
358+
NonZeroOid, Repo,
358359
};
359360
use crate::util::ExitCode;
360361

@@ -487,10 +488,15 @@ mod in_memory {
487488
let current_commit = repo
488489
.find_commit_or_fail(current_oid)
489490
.wrap_err("Finding current commit")?;
490-
let commit_to_apply_oid = match commits_to_apply_oids.as_slice() {
491-
[commit_to_apply_oid] => commit_to_apply_oid,
492-
[..] => unimplemented!("Picking multiple commits"),
493-
};
491+
let (commit_to_apply_oid, fixup_commit_oids) =
492+
match commits_to_apply_oids.as_slice() {
493+
[] => eyre::bail!("BUG: No commits to apply!"),
494+
[commit_to_apply_oid] => (commit_to_apply_oid, Vec::new()),
495+
[commit_to_apply_oid, fixup_commits @ ..] => {
496+
(commit_to_apply_oid, Vec::from(fixup_commits))
497+
}
498+
};
499+
494500
let commit_to_apply = repo
495501
.find_commit_or_fail(*commit_to_apply_oid)
496502
.wrap_err("Finding commit to apply")?;
@@ -549,7 +555,7 @@ mod in_memory {
549555
} else {
550556
commit_to_apply.get_committer().update_timestamp(*now)?
551557
};
552-
let rebased_commit_oid = repo
558+
let mut rebased_commit_oid = repo
553559
.create_commit(
554560
None,
555561
&commit_to_apply.get_author(),
@@ -560,9 +566,45 @@ mod in_memory {
560566
)
561567
.wrap_err("Applying rebased commit")?;
562568

563-
let rebased_commit = repo
569+
let mut rebased_commit = repo
564570
.find_commit_or_fail(rebased_commit_oid)
565571
.wrap_err("Looking up just-rebased commit")?;
572+
573+
for fixup_commit_oid in fixup_commit_oids.iter() {
574+
let fixup_commit = repo
575+
.find_commit_or_fail(*fixup_commit_oid)
576+
.wrap_err("Finding commit to apply")?;
577+
let fixup_commit_description = printable_styled_string(
578+
effects.get_glyphs(),
579+
fixup_commit.friendly_describe(effects.get_glyphs())?,
580+
)?;
581+
progress.notify_status(format!(
582+
"Applying patch for commit: {}",
583+
fixup_commit_description
584+
));
585+
let commit_tree = repo.amend_fast(
586+
&rebased_commit,
587+
&AmendFastOptions::FromCommit {
588+
commit: fixup_commit,
589+
},
590+
)?;
591+
592+
rebased_commit_oid = repo
593+
.create_commit(
594+
None,
595+
&rebased_commit.get_author(),
596+
&committer_signature,
597+
commit_message,
598+
&commit_tree,
599+
vec![&current_commit],
600+
)
601+
.wrap_err("Applying rebased commit")?;
602+
603+
rebased_commit = repo
604+
.find_commit_or_fail(rebased_commit_oid)
605+
.wrap_err("Looking up just-rebased commit")?;
606+
}
607+
566608
let commit_description = printable_styled_string(
567609
effects.get_glyphs(),
568610
repo.friendly_describe_commit_from_oid(
@@ -576,16 +618,22 @@ mod in_memory {
576618

577619
writeln!(
578620
effects.get_output_stream(),
579-
"[{}/{}] Skipped now-empty commit: {}",
580-
i,
581-
num_picks,
621+
"{} Skipped now-empty commit: {}",
622+
commit_num,
582623
commit_description
583624
)?;
584625
} else {
585626
rewritten_oids.insert(
586627
*original_commit_oid,
587628
MaybeZeroOid::NonZero(rebased_commit_oid),
588629
);
630+
for fixup_commit_oid in fixup_commit_oids {
631+
rewritten_oids.insert(
632+
fixup_commit_oid,
633+
MaybeZeroOid::NonZero(rebased_commit_oid),
634+
);
635+
}
636+
589637
current_oid = rebased_commit_oid;
590638

591639
writeln!(

0 commit comments

Comments
 (0)