1
1
use std:: { path:: Path , time} ;
2
2
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 } ;
4
11
use gitbutler_branch:: GITBUTLER_WORKSPACE_REFERENCE ;
5
12
use gitbutler_command_context:: CommandContext ;
6
13
use gitbutler_error:: error:: Marker ;
14
+ use gitbutler_oxidize:: { git2_to_gix_object_id, gix_to_git2_oid} ;
7
15
use gitbutler_project:: FetchResult ;
8
16
use gitbutler_reference:: { Refname , RemoteRefname } ;
9
- use gitbutler_repo:: { LogUntil , RepositoryExt } ;
17
+ use gitbutler_repo:: { GixRepositoryExt , LogUntil , RepositoryExt } ;
10
18
use gitbutler_repo_actions:: RepoActionsExt ;
11
19
use gitbutler_stack:: { BranchOwnershipClaims , Stack , Target , VirtualBranchesHandle } ;
20
+ use gix:: prelude:: Write ;
12
21
use serde:: Serialize ;
13
22
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
-
22
23
#[ derive( Debug , Serialize , PartialEq , Clone ) ]
23
24
#[ serde( rename_all = "camelCase" ) ]
24
25
pub struct BaseBranch {
@@ -50,8 +51,8 @@ pub(crate) fn get_base_branch_data(ctx: &CommandContext) -> Result<BaseBranch> {
50
51
}
51
52
52
53
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
55
56
. statuses ( Some (
56
57
git2:: StatusOptions :: new ( )
57
58
. show ( git2:: StatusShow :: IndexAndWorkdir )
@@ -67,41 +68,39 @@ fn go_back_to_integration(ctx: &CommandContext, default_target: &Target) -> Resu
67
68
. list_branches_in_workspace ( )
68
69
. context ( "failed to read virtual branches" ) ?;
69
70
70
- let target_commit = ctx
71
- . repository ( )
71
+ let target_commit = repo
72
72
. find_commit ( default_target. sha )
73
73
. context ( "failed to find target commit" ) ?;
74
74
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 ( ) ?;
81
79
for branch in & virtual_branches {
82
80
// 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}" ) ) ?;
101
100
}
102
101
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)
105
104
. force ( )
106
105
. checkout ( )
107
106
. context ( "failed to checkout tree" ) ?;
0 commit comments