@@ -9,10 +9,12 @@ use gitbutler_command_context::CommandContext;
99use gitbutler_commit:: commit_ext:: CommitExt ;
1010use gitbutler_error:: error:: Marker ;
1111use gitbutler_operating_modes:: OPEN_WORKSPACE_REFS ;
12+ use gitbutler_oxidize:: { git2_to_gix_object_id, gix_to_git2_oid} ;
1213use gitbutler_project:: access:: WorktreeWritePermission ;
13- use gitbutler_repo:: SignaturePurpose ;
14+ use gitbutler_repo:: { GixRepositoryExt , SignaturePurpose } ;
1415use gitbutler_repo:: { LogUntil , RepositoryExt } ;
1516use gitbutler_stack:: { Stack , VirtualBranchesHandle } ;
17+ use gix:: objs:: Write ;
1618use tracing:: instrument;
1719
1820use crate :: { branch_manager:: BranchManagerExt , conflicts, VirtualBranchesExt } ;
@@ -41,6 +43,7 @@ pub(crate) fn get_workspace_head(ctx: &CommandContext) -> Result<git2::Oid> {
4143
4244 let target_commit = repo. find_commit ( target. sha ) ?;
4345 let mut workspace_tree = repo. find_real_tree ( & target_commit, Default :: default ( ) ) ?;
46+ let mut workspace_tree_id = git2_to_gix_object_id ( workspace_tree. id ( ) ) ;
4447
4548 if conflicts:: is_conflicting ( ctx, None ) ? {
4649 let merge_parent = conflicts:: merge_parent ( ctx) ?. ok_or ( anyhow ! ( "No merge parent" ) ) ?;
@@ -49,22 +52,37 @@ pub(crate) fn get_workspace_head(ctx: &CommandContext) -> Result<git2::Oid> {
4952 let merge_base = repo. merge_base ( first_branch. head ( ) , merge_parent) ?;
5053 workspace_tree = repo. find_commit ( merge_base) ?. tree ( ) ?;
5154 } else {
55+ let gix_repo = ctx. gix_repository_for_merging ( ) ?;
56+ let mut merge_options_fail_fast = gix_repo. tree_merge_options ( ) ?;
57+ let conflict_kind = gix:: merge:: tree:: UnresolvedConflict :: Renames ;
58+ merge_options_fail_fast. fail_on_conflict = Some ( conflict_kind) ;
59+ let merge_tree_id = git2_to_gix_object_id ( repo. find_commit ( target. sha ) ?. tree_id ( ) ) ;
5260 for branch in virtual_branches. iter_mut ( ) {
53- let merge_tree = repo. find_commit ( target. sha ) ?. tree ( ) ?;
54- let branch_tree = repo. find_commit ( branch. head ( ) ) ?;
55- let branch_tree = repo. find_real_tree ( & branch_tree, Default :: default ( ) ) ?;
56-
57- let mut index = repo. merge_trees ( & merge_tree, & workspace_tree, & branch_tree, None ) ?;
61+ let branch_head = repo. find_commit ( branch. head ( ) ) ?;
62+ let branch_tree_id =
63+ git2_to_gix_object_id ( repo. find_real_tree ( & branch_head, Default :: default ( ) ) ?. id ( ) ) ;
64+
65+ let mut merge = gix_repo. merge_trees (
66+ merge_tree_id,
67+ workspace_tree_id,
68+ branch_tree_id,
69+ gix_repo. default_merge_labels ( ) ,
70+ merge_options_fail_fast. clone ( ) ,
71+ ) ?;
5872
59- if !index. has_conflicts ( ) {
60- workspace_tree = repo. find_tree ( index. write_tree_to ( repo) ?) ?;
73+ if !merge. has_unresolved_conflicts ( conflict_kind) {
74+ workspace_tree_id = merge
75+ . tree
76+ . write ( |tree| gix_repo. write ( tree) )
77+ . map_err ( |err| anyhow ! ( "{err}" ) ) ?;
6178 } else {
6279 // This branch should have already been unapplied during the "update" command but for some reason that failed
6380 tracing:: warn!( "Merge conflict between base and {:?}" , branch. name) ;
6481 branch. in_workspace = false ;
6582 vb_state. set_branch ( branch. clone ( ) ) ?;
6683 }
6784 }
85+ workspace_tree = repo. find_tree ( gix_to_git2_oid ( workspace_tree_id) ) ?;
6886 }
6987
7088 let committer = gitbutler_repo:: signature ( SignaturePurpose :: Committer ) ?;
0 commit comments