Add an option to cherry rebase to always rebase

This commit is contained in:
Kiril Videlov 2024-11-20 19:41:15 +01:00
parent 7a90cfa6c9
commit d8f321b8f6
No known key found for this signature in database
GPG Key ID: A4C733025427C471
9 changed files with 52 additions and 27 deletions

View File

@ -336,7 +336,8 @@ impl BranchManager<'_> {
let commits_to_rebase =
repo.l(stack.head(), LogUntil::Commit(merge_base), false)?;
let head_oid = cherry_rebase_group(repo, default_target.sha, &commits_to_rebase)?;
let head_oid =
cherry_rebase_group(repo, default_target.sha, &commits_to_rebase, true)?;
repo.find_commit(head_oid)?
} else {

View File

@ -207,7 +207,7 @@ impl IntegrateUpstreamContext<'_, '_> {
)?;
// First rebase the series with it's remote commits
let new_series_head =
cherry_rebase_group(self.repository, merge_base, &ordered_commits)?;
cherry_rebase_group(self.repository, merge_base, &ordered_commits, false)?;
// Get the commits that come after the series head, until the stack head
let remaining_ids_to_rebase =
self.repository
@ -218,6 +218,7 @@ impl IntegrateUpstreamContext<'_, '_> {
self.repository,
new_series_head,
&remaining_ids_to_rebase,
false,
)?,
new_series_head,
)
@ -233,6 +234,7 @@ impl IntegrateUpstreamContext<'_, '_> {
self.repository,
remote_head_commit.id(),
&remaining_ids_to_rebase,
false,
)?,
remote_head_commit.id(),
)
@ -276,7 +278,7 @@ impl IntegrateUpstreamContext<'_, '_> {
self.remote_head,
)?;
cherry_rebase_group(self.repository, merge_base, &ordered_commits)?
cherry_rebase_group(self.repository, merge_base, &ordered_commits, false)?
}
IntegrationStrategy::HardReset => self.remote_head,
};

View File

@ -131,8 +131,12 @@ fn take_commit_from_source_stack(
let source_commits_without_subject =
filter_out_commit(repo, source_stack, source_merge_base_oid, &subject_commit)?;
let new_source_head =
cherry_rebase_group(repo, source_merge_base_oid, &source_commits_without_subject)?;
let new_source_head = cherry_rebase_group(
repo,
source_merge_base_oid,
&source_commits_without_subject,
false,
)?;
let BranchHeadAndTree {
head: new_head_oid,
@ -154,7 +158,7 @@ fn move_commit_to_destination_stack(
) -> Result<(), anyhow::Error> {
let destination_head_commit_oid = destination_stack.head();
let new_destination_head_oid =
cherry_rebase_group(repo, destination_head_commit_oid, &[commit_id])?;
cherry_rebase_group(repo, destination_head_commit_oid, &[commit_id], false)?;
let BranchHeadAndTree {
head: new_destination_head_oid,

View File

@ -54,7 +54,7 @@ pub fn reorder_stack(
.flat_map(|s| s.commit_ids.iter())
.cloned()
.collect_vec();
let new_head = cherry_rebase_group(repo, merge_base, &ids_to_rebase)?;
let new_head = cherry_rebase_group(repo, merge_base, &ids_to_rebase, false)?;
// Calculate the new head and tree
let BranchHeadAndTree {
head: new_head_oid,

View File

@ -109,6 +109,7 @@ fn inner_undo_commit(
repository,
commit_to_remove.parent_id(0)?,
&commits_to_rebase,
false,
)?;
Ok(UndoResult {

View File

@ -265,7 +265,7 @@ fn get_stack_status(
let rebase_base = last_head;
let new_head_oid = cherry_rebase_group(repository, rebase_base, &local_commit_ids)?;
let new_head_oid = cherry_rebase_group(repository, rebase_base, &local_commit_ids, false)?;
let rebased_commits = repository.log(new_head_oid, LogUntil::Commit(rebase_base), false)?;
last_head = new_head_oid;
@ -514,7 +514,7 @@ pub(crate) fn resolve_upstream_integration(
}
BaseBranchResolutionApproach::Rebase => {
let commits = repo.l(old_target_id, LogUntil::Commit(fork_point), false)?;
let new_head = cherry_rebase_group(repo, new_target_id, &commits)?;
let new_head = cherry_rebase_group(repo, new_target_id, &commits, false)?;
Ok(new_head)
}
@ -626,8 +626,12 @@ fn compute_resolutions(
})
.collect::<Vec<_>>();
let new_head =
cherry_rebase_group(repository, new_target.id(), &virtual_branch_commits)?;
let new_head = cherry_rebase_group(
repository,
new_target.id(),
&virtual_branch_commits,
false,
)?;
// Get the updated tree oid
let BranchHeadAndTree {

View File

@ -1599,7 +1599,7 @@ pub(crate) fn squash(ctx: &CommandContext, stack_id: StackId, commit_id: git2::O
.with_context(|| format!("commit {commit_id} not in the branch"))?;
let ids_to_rebase = ids_to_rebase.to_vec();
match cherry_rebase_group(ctx.repository(), new_commit_oid, &ids_to_rebase) {
match cherry_rebase_group(ctx.repository(), new_commit_oid, &ids_to_rebase, false) {
Ok(new_head_id) => {
// save new branch head
stack.set_stack_head(ctx, new_head_id, None)?;
@ -1678,7 +1678,7 @@ pub(crate) fn update_commit_message(
.with_context(|| format!("commit {commit_id} not in the branch"))?;
let ids_to_rebase = ids_to_rebase.to_vec();
let new_head_id = cherry_rebase_group(ctx.repository(), new_commit_oid, &ids_to_rebase)
let new_head_id = cherry_rebase_group(ctx.repository(), new_commit_oid, &ids_to_rebase, false)
.map_err(|err| err.context("rebase error"))?;
// save new branch head
stack.set_stack_head(ctx, new_head_id, None)?;

View File

@ -35,7 +35,8 @@ pub fn cherry_rebase(
return Ok(None);
}
let new_head_id = cherry_rebase_group(ctx.repository(), target_commit_oid, &ids_to_rebase)?;
let new_head_id =
cherry_rebase_group(ctx.repository(), target_commit_oid, &ids_to_rebase, false)?;
Ok(Some(new_head_id))
}
@ -50,6 +51,7 @@ pub fn cherry_rebase_group(
repository: &git2::Repository,
target_commit_oid: git2::Oid,
ids_to_rebase: &[git2::Oid],
always_rebase: bool,
) -> Result<git2::Oid> {
// now, rebase unchanged commits onto the new commit
let commits_to_rebase = ids_to_rebase
@ -68,7 +70,10 @@ pub fn cherry_rebase_group(
|head, to_rebase| {
let head = head?;
if to_rebase.parent_ids().len() == 1 && head.id() == to_rebase.parent_id(0)? {
if !always_rebase
&& to_rebase.parent_ids().len() == 1
&& head.id() == to_rebase.parent_id(0)?
{
return Ok(to_rebase);
};
@ -452,9 +457,13 @@ mod test {
let c = test_repository.commit_tree(Some(&b), &[("foo.txt", "c"), ("bar.txt", "a")]);
let d = test_repository.commit_tree(Some(&a), &[("foo.txt", "a"), ("bar.txt", "x")]);
let result =
cherry_rebase_group(&test_repository.repository, d.id(), &[c.id(), b.id()])
.unwrap();
let result = cherry_rebase_group(
&test_repository.repository,
d.id(),
&[c.id(), b.id()],
false,
)
.unwrap();
let commit: git2::Commit = test_repository.repository.find_commit(result).unwrap();
@ -482,7 +491,7 @@ mod test {
// Rebase C on top of B
let result =
cherry_rebase_group(&test_repository.repository, b.id(), &[c.id()]).unwrap();
cherry_rebase_group(&test_repository.repository, b.id(), &[c.id()], false).unwrap();
let commit: git2::Commit = test_repository.repository.find_commit(result).unwrap();
@ -511,11 +520,11 @@ mod test {
// Rebase C on top of B => C'
let result =
cherry_rebase_group(&test_repository.repository, b.id(), &[c.id()]).unwrap();
cherry_rebase_group(&test_repository.repository, b.id(), &[c.id()], false).unwrap();
// Rebase C' on top of D => C''
let result =
cherry_rebase_group(&test_repository.repository, d.id(), &[result]).unwrap();
cherry_rebase_group(&test_repository.repository, d.id(), &[result], false).unwrap();
let commit: git2::Commit = test_repository.repository.find_commit(result).unwrap();
@ -545,7 +554,7 @@ mod test {
// Rebase D on top of B => D'
let result =
cherry_rebase_group(&test_repository.repository, b.id(), &[d.id()]).unwrap();
cherry_rebase_group(&test_repository.repository, b.id(), &[d.id()], false).unwrap();
let commit: git2::Commit = test_repository.repository.find_commit(result).unwrap();
assert!(commit.is_conflicted());
@ -563,7 +572,7 @@ mod test {
// Rebase D' on top of C => D''
let result =
cherry_rebase_group(&test_repository.repository, c.id(), &[result]).unwrap();
cherry_rebase_group(&test_repository.repository, c.id(), &[result], false).unwrap();
let commit: git2::Commit = test_repository.repository.find_commit(result).unwrap();
assert!(commit.is_conflicted());
@ -590,9 +599,13 @@ mod test {
let d = test_repository.commit_tree(Some(&a), &[("foo.txt", "c"), ("bar.txt", "c")]);
// Rebase C on top of B
let result =
cherry_rebase_group(&test_repository.repository, d.id(), &[c.id(), b.id()])
.unwrap();
let result = cherry_rebase_group(
&test_repository.repository,
d.id(),
&[c.id(), b.id()],
false,
)
.unwrap();
let commit: git2::Commit = test_repository.repository.find_commit(result).unwrap();

View File

@ -129,7 +129,7 @@ pub fn compute_updated_branch_head_for_commits(
Default::default(),
)?;
let rebased_tree = cherry_rebase_group(repository, new_head, &[commited_tree])?;
let rebased_tree = cherry_rebase_group(repository, new_head, &[commited_tree], false)?;
let rebased_tree = repository.find_commit(rebased_tree)?;
if rebased_tree.is_conflicted() {