Skip to content

Commit bda1877

Browse files
feat(rebase): Update RebaseCommand::Pick to support squashing commits
1 parent 3e531cb commit bda1877

File tree

2 files changed

+261
-56
lines changed

2 files changed

+261
-56
lines changed

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

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,8 @@ mod in_memory {
386386
use crate::core::rewrite::move_branches;
387387
use crate::core::rewrite::plan::{OidOrLabel, RebaseCommand, RebasePlan};
388388
use crate::git::{
389-
CherryPickFastError, CherryPickFastOptions, GitRunInfo, MaybeZeroOid, NonZeroOid, Repo,
389+
AmendFastOptions, CherryPickFastError, CherryPickFastOptions, GitRunInfo, MaybeZeroOid,
390+
NonZeroOid, Repo,
390391
};
391392
use crate::util::ExitCode;
392393

@@ -519,10 +520,15 @@ mod in_memory {
519520
let current_commit = repo
520521
.find_commit_or_fail(current_oid)
521522
.wrap_err("Finding current commit")?;
522-
let commit_to_apply_oid = match commits_to_apply_oids.as_slice() {
523-
[commit_to_apply_oid] => commit_to_apply_oid,
524-
[..] => unimplemented!("Picking multiple commits"),
525-
};
523+
let (commit_to_apply_oid, fixup_commit_oids) =
524+
match commits_to_apply_oids.as_slice() {
525+
[] => eyre::bail!("BUG: No commits to apply!"),
526+
[commit_to_apply_oid] => (commit_to_apply_oid, Vec::new()),
527+
[commit_to_apply_oid, fixup_commits @ ..] => {
528+
(commit_to_apply_oid, Vec::from(fixup_commits))
529+
}
530+
};
531+
526532
let commit_to_apply = repo
527533
.find_commit_or_fail(*commit_to_apply_oid)
528534
.wrap_err("Finding commit to apply")?;
@@ -580,7 +586,7 @@ mod in_memory {
580586
} else {
581587
commit_to_apply.get_committer().update_timestamp(*now)?
582588
};
583-
let rebased_commit_oid = repo
589+
let mut rebased_commit_oid = repo
584590
.create_commit(
585591
None,
586592
&commit_to_apply.get_author(),
@@ -591,9 +597,44 @@ mod in_memory {
591597
)
592598
.wrap_err("Applying rebased commit")?;
593599

594-
let rebased_commit = repo
600+
let mut rebased_commit = repo
595601
.find_commit_or_fail(rebased_commit_oid)
596602
.wrap_err("Looking up just-rebased commit")?;
603+
604+
for fixup_commit_oid in fixup_commit_oids.iter() {
605+
let fixup_commit = repo
606+
.find_commit_or_fail(*fixup_commit_oid)
607+
.wrap_err("Finding commit to apply")?;
608+
let fixup_commit_description = effects
609+
.get_glyphs()
610+
.render(fixup_commit.friendly_describe(effects.get_glyphs())?)?;
611+
progress.notify_status(format!(
612+
"Applying patch for commit: {}",
613+
fixup_commit_description
614+
));
615+
let commit_tree = repo.amend_fast(
616+
&rebased_commit,
617+
&AmendFastOptions::FromCommit {
618+
commit: fixup_commit,
619+
},
620+
)?;
621+
622+
rebased_commit_oid = repo
623+
.create_commit(
624+
None,
625+
&rebased_commit.get_author(),
626+
&committer_signature,
627+
commit_message,
628+
&commit_tree,
629+
vec![&current_commit],
630+
)
631+
.wrap_err("Applying rebased commit")?;
632+
633+
rebased_commit = repo
634+
.find_commit_or_fail(rebased_commit_oid)
635+
.wrap_err("Looking up just-rebased commit")?;
636+
}
637+
597638
let commit_description =
598639
effects
599640
.get_glyphs()
@@ -607,16 +648,22 @@ mod in_memory {
607648

608649
writeln!(
609650
effects.get_output_stream(),
610-
"[{}/{}] Skipped now-empty commit: {}",
611-
i,
612-
num_picks,
651+
"{} Skipped now-empty commit: {}",
652+
commit_num,
613653
commit_description
614654
)?;
615655
} else {
616656
rewritten_oids.insert(
617657
*original_commit_oid,
618658
MaybeZeroOid::NonZero(rebased_commit_oid),
619659
);
660+
for fixup_commit_oid in fixup_commit_oids {
661+
rewritten_oids.insert(
662+
fixup_commit_oid,
663+
MaybeZeroOid::NonZero(rebased_commit_oid),
664+
);
665+
}
666+
620667
current_oid = rebased_commit_oid;
621668

622669
writeln!(

0 commit comments

Comments
 (0)