Skip to content

Commit 5b258e2

Browse files
committed
Use gitoxide when merging trees in go_back_to_integration().`
1 parent fb251ec commit 5b258e2

File tree

1 file changed

+39
-40
lines changed
  • crates/gitbutler-branch-actions/src

1 file changed

+39
-40
lines changed

crates/gitbutler-branch-actions/src/base.rs

+39-40
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
11
use std::{path::Path, time};
22

3-
use anyhow::{anyhow, Context, Result};
3+
use crate::{
4+
conflicts::RepoConflictsExt,
5+
hunk::VirtualBranchHunk,
6+
integration::update_workspace_commit,
7+
remote::{commit_to_remote_commit, RemoteCommit},
8+
VirtualBranchesExt,
9+
};
10+
use anyhow::{anyhow, bail, Context, Result};
411
use gitbutler_branch::GITBUTLER_WORKSPACE_REFERENCE;
512
use gitbutler_command_context::CommandContext;
613
use gitbutler_error::error::Marker;
14+
use gitbutler_oxidize::{git2_to_gix_object_id, gix_to_git2_oid};
715
use gitbutler_project::FetchResult;
816
use gitbutler_reference::{Refname, RemoteRefname};
9-
use gitbutler_repo::{LogUntil, RepositoryExt};
17+
use gitbutler_repo::{GixRepositoryExt, LogUntil, RepositoryExt};
1018
use gitbutler_repo_actions::RepoActionsExt;
1119
use gitbutler_stack::{BranchOwnershipClaims, Stack, Target, VirtualBranchesHandle};
20+
use gix::prelude::Write;
1221
use serde::Serialize;
1322

14-
use crate::{
15-
conflicts::RepoConflictsExt,
16-
hunk::VirtualBranchHunk,
17-
integration::update_workspace_commit,
18-
remote::{commit_to_remote_commit, RemoteCommit},
19-
VirtualBranchesExt,
20-
};
21-
2223
#[derive(Debug, Serialize, PartialEq, Clone)]
2324
#[serde(rename_all = "camelCase")]
2425
pub struct BaseBranch {
@@ -50,8 +51,8 @@ pub(crate) fn get_base_branch_data(ctx: &CommandContext) -> Result<BaseBranch> {
5051
}
5152

5253
fn go_back_to_integration(ctx: &CommandContext, default_target: &Target) -> Result<BaseBranch> {
53-
let statuses = ctx
54-
.repository()
54+
let repo = ctx.repository();
55+
let statuses = repo
5556
.statuses(Some(
5657
git2::StatusOptions::new()
5758
.show(git2::StatusShow::IndexAndWorkdir)
@@ -67,41 +68,39 @@ fn go_back_to_integration(ctx: &CommandContext, default_target: &Target) -> Resu
6768
.list_branches_in_workspace()
6869
.context("failed to read virtual branches")?;
6970

70-
let target_commit = ctx
71-
.repository()
71+
let target_commit = repo
7272
.find_commit(default_target.sha)
7373
.context("failed to find target commit")?;
7474

75-
let base_tree = target_commit
76-
.tree()
77-
.context("failed to get base tree from commit")?;
78-
let mut final_tree = target_commit
79-
.tree()
80-
.context("failed to get base tree from commit")?;
75+
let base_tree = git2_to_gix_object_id(target_commit.tree_id());
76+
let mut final_tree_id = git2_to_gix_object_id(target_commit.tree_id());
77+
let gix_repo = ctx.gix_repository_for_merging()?;
78+
let (merge_options_fail_fast, conflict_kind) = gix_repo.merge_options_fail_fast()?;
8179
for branch in &virtual_branches {
8280
// merge this branches tree with our tree
83-
let branch_head = ctx
84-
.repository()
85-
.find_commit(branch.head())
86-
.context("failed to find branch head")?;
87-
let branch_tree = branch_head
88-
.tree()
89-
.context("failed to get branch head tree")?;
90-
let mut result = ctx
91-
.repository()
92-
.merge_trees(&base_tree, &final_tree, &branch_tree, None)
93-
.context("failed to merge")?;
94-
let final_tree_oid = result
95-
.write_tree_to(ctx.repository())
96-
.context("failed to write tree")?;
97-
final_tree = ctx
98-
.repository()
99-
.find_tree(final_tree_oid)
100-
.context("failed to find written tree")?;
81+
let branch_tree_id = git2_to_gix_object_id(
82+
repo.find_commit(branch.head())
83+
.context("failed to find branch head")?
84+
.tree_id(),
85+
);
86+
let mut merge = gix_repo.merge_trees(
87+
base_tree,
88+
final_tree_id,
89+
branch_tree_id,
90+
gix_repo.default_merge_labels(),
91+
merge_options_fail_fast.clone(),
92+
)?;
93+
if merge.has_unresolved_conflicts(conflict_kind) {
94+
bail!("Merge failed with conflicts");
95+
}
96+
final_tree_id = merge
97+
.tree
98+
.write(|tree| gix_repo.write(tree))
99+
.map_err(|err| anyhow!("failed to write tree: {err}"))?;
101100
}
102101

103-
ctx.repository()
104-
.checkout_tree_builder(&final_tree)
102+
let final_tree = repo.find_tree(gix_to_git2_oid(final_tree_id))?;
103+
repo.checkout_tree_builder(&final_tree)
105104
.force()
106105
.checkout()
107106
.context("failed to checkout tree")?;

0 commit comments

Comments
 (0)