@@ -8,7 +8,7 @@ use git2::build::CheckoutBuilder;
8
8
use gitbutler_branch_actions:: internal:: list_virtual_branches;
9
9
use gitbutler_branch_actions:: { update_workspace_commit, RemoteBranchFile } ;
10
10
use gitbutler_cherry_pick:: { ConflictedTreeKey , RepositoryExt as _} ;
11
- use gitbutler_command_context:: CommandContext ;
11
+ use gitbutler_command_context:: { gix_repository_for_merging , CommandContext } ;
12
12
use gitbutler_commit:: {
13
13
commit_ext:: CommitExt ,
14
14
commit_headers:: { CommitHeadersV2 , HasCommitHeaders } ,
@@ -18,6 +18,7 @@ use gitbutler_operating_modes::{
18
18
operating_mode, read_edit_mode_metadata, write_edit_mode_metadata, EditModeMetadata ,
19
19
OperatingMode , EDIT_BRANCH_REF , WORKSPACE_BRANCH_REF ,
20
20
} ;
21
+ use gitbutler_oxidize:: { git2_to_gix_object_id, gix_to_git2_index, GixRepositoryExt } ;
21
22
use gitbutler_project:: access:: { WorktreeReadPermission , WorktreeWritePermission } ;
22
23
use gitbutler_reference:: { ReferenceName , Refname } ;
23
24
use gitbutler_repo:: { rebase:: cherry_rebase, RepositoryExt } ;
@@ -34,36 +35,38 @@ fn get_commit_index(repository: &git2::Repository, commit: &git2::Commit) -> Res
34
35
if commit. is_conflicted ( ) {
35
36
let base = commit_tree
36
37
. get_name ( ".conflict-base-0" )
37
- . context ( "Failed to get base" ) ?;
38
- let base = repository
39
- . find_tree ( base. id ( ) )
40
- . context ( "Failed to find base tree" ) ?;
41
- // Ours
38
+ . context ( "Failed to get base" ) ?
39
+ . id ( ) ;
42
40
let ours = commit_tree
43
41
. get_name ( ".conflict-side-0" )
44
- . context ( "Failed to get base" ) ?;
45
- let ours = repository
46
- . find_tree ( ours. id ( ) )
47
- . context ( "Failed to find base tree" ) ?;
48
- // Theirs
42
+ . context ( "Failed to get base" ) ?
43
+ . id ( ) ;
49
44
let theirs = commit_tree
50
45
. get_name ( ".conflict-side-1" )
51
- . context ( "Failed to get base" ) ?;
52
- let theirs = repository
53
- . find_tree ( theirs. id ( ) )
54
- . context ( "Failed to find base tree" ) ?;
55
-
56
- let index = repository
57
- . merge_trees ( & base, & ours, & theirs, None )
58
- . context ( "Failed to merge trees" ) ?;
59
-
60
- Ok ( index)
46
+ . context ( "Failed to get base" ) ?
47
+ . id ( ) ;
48
+
49
+ let gix_repo = gix_repository_for_merging ( repository. path ( ) ) ?;
50
+ // Merge without favoring a side this time to get a tree containing the actual conflicts.
51
+ let mut merge_result = gix_repo. merge_trees (
52
+ git2_to_gix_object_id ( base) ,
53
+ git2_to_gix_object_id ( ours) ,
54
+ git2_to_gix_object_id ( theirs) ,
55
+ gix_repo. default_merge_labels ( ) ,
56
+ gix_repo. tree_merge_options ( ) ?,
57
+ ) ?;
58
+ let merged_tree_id = merge_result. tree . write ( ) ?;
59
+ let mut index = gix_repo. index_from_tree ( & merged_tree_id) ?;
60
+ if !merge_result. index_changed_after_applying_conflicts (
61
+ & mut index,
62
+ gix:: merge:: tree:: TreatAsUnresolved :: git ( ) ,
63
+ ) {
64
+ tracing:: warn!( "There must be an issue with conflict-commit creation as re-merging the conflicting trees didn't yield a conflicting index." ) ;
65
+ }
66
+ gix_to_git2_index ( & index)
61
67
} else {
62
68
let mut index = git2:: Index :: new ( ) ?;
63
- index
64
- . read_tree ( & commit_tree)
65
- . context ( "Failed to set index tree" ) ?;
66
-
69
+ index. read_tree ( & commit_tree) ?;
67
70
Ok ( index)
68
71
}
69
72
}
0 commit comments