@@ -18,6 +18,7 @@ use crate::string_array::StringArray;
1818use crate :: tagforeach:: { tag_foreach_cb, TagForeachCB , TagForeachData } ;
1919use crate :: util:: { self , path_to_repo_path, Binding } ;
2020use crate :: worktree:: { Worktree , WorktreeAddOptions } ;
21+ use crate :: CherrypickOptions ;
2122use crate :: RevertOptions ;
2223use crate :: {
2324 raw, AttrCheckFlags , Buf , Error , Object , Remote , RepositoryOpenFlags , RepositoryState , Revspec ,
@@ -29,7 +30,6 @@ use crate::{
2930use crate :: { ApplyLocation , ApplyOptions , Rebase , RebaseOptions } ;
3031use crate :: { Blame , BlameOptions , Reference , References , ResetType , Signature , Submodule } ;
3132use crate :: { Blob , BlobWriter , Branch , BranchType , Branches , Commit , Config , Index , Oid , Tree } ;
32- use crate :: { CherrypickOptions , IndexEntry } ;
3333use crate :: { Describe , IntoCString , Reflog , RepositoryInitMode , RevparseMode } ;
3434use crate :: { DescribeOptions , Diff , DiffOptions , Odb , PackBuilder , TreeBuilder } ;
3535use crate :: { Note , Notes , ObjectType , Revwalk , Status , StatusOptions , Statuses , Tag } ;
@@ -1848,47 +1848,13 @@ impl Repository {
18481848 ///
18491849 /// Note that this function does not reference a repository and any
18501850 /// configuration must be passed as `git_merge_file_options`.
1851- ///
1852- /// @param out The git_merge_file_result to be filled in
1853- /// @param ancestor The contents of the ancestor file
1854- /// @param ours The contents of the file in "our" side
1855- /// @param theirs The contents of the file in "their" side
1856- /// @param opts The merge file options or `NULL` for defaults
1857- /// @return 0 on success or error code
18581851 pub fn merge_file (
18591852 & self ,
1860- ancestor : Option < & IndexEntry > ,
1861- ours : Option < & IndexEntry > ,
1862- theirs : Option < & IndexEntry > ,
1853+ ancestor : Option < & MergeFileInput < ' _ > > ,
1854+ ours : Option < & MergeFileInput < ' _ > > ,
1855+ theirs : Option < & MergeFileInput < ' _ > > ,
18631856 options : Option < & MergeFileOptions > ,
18641857 ) -> Result < MergeFileResult , Error > {
1865- let ancestor_input;
1866- let ours_input;
1867- let theirs_input;
1868-
1869- let ancestor_raw;
1870- let ours_raw;
1871- let theirs_raw;
1872-
1873- if let Some ( ancestor) = ancestor {
1874- ancestor_input = MergeFileInput :: from ( & self , ancestor) ;
1875- ancestor_raw = ancestor_input. raw ( ) ;
1876- } else {
1877- ancestor_raw = ptr:: null ( ) ;
1878- }
1879- if let Some ( ours) = ours {
1880- ours_input = MergeFileInput :: from ( & self , ours) ;
1881- ours_raw = ours_input. raw ( ) ;
1882- } else {
1883- ours_raw = ptr:: null ( ) ;
1884- }
1885- if let Some ( theirs) = theirs {
1886- theirs_input = MergeFileInput :: from ( & self , theirs) ;
1887- theirs_raw = theirs_input. raw ( ) ;
1888- } else {
1889- theirs_raw = ptr:: null ( ) ;
1890- }
1891-
18921858 let mut ret = raw:: git_merge_file_result {
18931859 automergeable : 0 ,
18941860 path : ptr:: null ( ) ,
@@ -1900,9 +1866,9 @@ impl Repository {
19001866 unsafe {
19011867 try_call ! ( raw:: git_merge_file(
19021868 & mut ret,
1903- ancestor_raw ,
1904- ours_raw ,
1905- theirs_raw ,
1869+ ancestor . map ( |a| a . raw ( ) ) . unwrap_or ( ptr :: null ( ) ) ,
1870+ ours . map ( |a| a . raw ( ) ) . unwrap_or ( ptr :: null ( ) ) ,
1871+ theirs . map ( |a| a . raw ( ) ) . unwrap_or ( ptr :: null ( ) ) ,
19061872 options. map( |o| o. raw( ) )
19071873 ) ) ;
19081874
@@ -3104,8 +3070,9 @@ impl RepositoryInitOptions {
31043070#[ cfg( test) ]
31053071mod tests {
31063072 use crate :: build:: CheckoutBuilder ;
3107- use crate :: { CherrypickOptions , FileMode } ;
3073+ use crate :: { CherrypickOptions , FileMode , MergeFileInput } ;
31083074 use crate :: { ObjectType , Oid , Repository , ResetType } ;
3075+ use std:: convert:: TryInto ;
31093076 use std:: ffi:: OsStr ;
31103077 use std:: fs;
31113078 use std:: io:: Write ;
@@ -3357,6 +3324,7 @@ mod tests {
33573324 file_a
33583325 . write_all ( file_on_branch_a_content_1. as_bytes ( ) )
33593326 . unwrap ( ) ;
3327+ drop ( file_a) ;
33603328 index. add_path ( Path :: new ( "file_a" ) ) . unwrap ( ) ;
33613329 let id_a = index. write_tree ( ) . unwrap ( ) ;
33623330 let tree_a = repo. find_tree ( id_a) . unwrap ( ) ;
@@ -3378,10 +3346,11 @@ mod tests {
33783346 // create commit oid3 on branchB
33793347 let mut index = repo. index ( ) . unwrap ( ) ;
33803348 let p = Path :: new ( repo. workdir ( ) . unwrap ( ) ) . join ( "file_a" ) ;
3381- let mut file_b = fs:: File :: create ( & p) . unwrap ( ) ;
3382- file_b
3349+ let mut file_a = fs:: File :: create ( & p) . unwrap ( ) ;
3350+ file_a
33833351 . write_all ( file_on_branch_b_content_1. as_bytes ( ) )
33843352 . unwrap ( ) ;
3353+ drop ( file_a) ;
33853354 index. add_path ( Path :: new ( "file_a" ) ) . unwrap ( ) ;
33863355 let id_b = index. write_tree ( ) . unwrap ( ) ;
33873356 let tree_b = repo. find_tree ( id_b) . unwrap ( ) ;
@@ -3405,6 +3374,7 @@ mod tests {
34053374 let p = Path :: new ( repo. workdir ( ) . unwrap ( ) ) . join ( "file_a" ) ;
34063375 let mut file_a = fs:: OpenOptions :: new ( ) . append ( true ) . open ( & p) . unwrap ( ) ;
34073376 file_a. write ( file_on_branch_a_content_2. as_bytes ( ) ) . unwrap ( ) ;
3377+ drop ( file_a) ;
34083378 index. add_path ( Path :: new ( "file_a" ) ) . unwrap ( ) ;
34093379 let id_a_2 = index. write_tree ( ) . unwrap ( ) ;
34103380 let tree_a_2 = repo. find_tree ( id_a_2) . unwrap ( ) ;
@@ -3423,11 +3393,12 @@ mod tests {
34233393
34243394 t ! ( repo. reset( commit3. as_object( ) , ResetType :: Hard , None ) ) ;
34253395
3426- // create commit oid4 on branchB
3396+ // create commit oid5 on branchB
34273397 let mut index = repo. index ( ) . unwrap ( ) ;
34283398 let p = Path :: new ( repo. workdir ( ) . unwrap ( ) ) . join ( "file_a" ) ;
34293399 let mut file_a = fs:: OpenOptions :: new ( ) . append ( true ) . open ( & p) . unwrap ( ) ;
34303400 file_a. write ( file_on_branch_b_content_2. as_bytes ( ) ) . unwrap ( ) ;
3401+ drop ( file_a) ;
34313402 index. add_path ( Path :: new ( "file_a" ) ) . unwrap ( ) ;
34323403 let id_b_2 = index. write_tree ( ) . unwrap ( ) ;
34333404 let tree_b_2 = repo. find_tree ( id_b_2) . unwrap ( ) ;
@@ -3457,11 +3428,63 @@ mod tests {
34573428 for conflict in index_conflicts {
34583429 let conflict = conflict. unwrap ( ) ;
34593430
3431+ let ancestor_input;
3432+ let ours_input;
3433+ let theirs_input;
3434+
3435+ let ancestor_blob;
3436+ let ours_blob;
3437+ let theirs_blob;
3438+
3439+ let ancestor_content;
3440+ let ours_content;
3441+ let theirs_content;
3442+
3443+ if let Some ( ancestor) = conflict. ancestor {
3444+ ancestor_blob = repo
3445+ . find_blob ( ancestor. id . clone ( ) )
3446+ . expect ( "failed to find blob of index entry to make MergeFileInput" ) ;
3447+ ancestor_content = ancestor_blob. content ( ) ;
3448+ let mut input = MergeFileInput :: new ( ) ;
3449+ input. path ( String :: from_utf8 ( ancestor. path ) . unwrap ( ) ) ;
3450+ input. mode ( Some ( FileMode :: from ( ancestor. mode . try_into ( ) . unwrap ( ) ) ) ) ;
3451+ input. content ( Some ( & ancestor_content) ) ;
3452+ ancestor_input = Some ( input) ;
3453+ } else {
3454+ ancestor_input = None ;
3455+ }
3456+ if let Some ( ours) = conflict. our {
3457+ ours_blob = repo
3458+ . find_blob ( ours. id . clone ( ) )
3459+ . expect ( "failed to find blob of index entry to make MergeFileInput" ) ;
3460+ ours_content = ours_blob. content ( ) ;
3461+ let mut input = MergeFileInput :: new ( ) ;
3462+ input. path ( String :: from_utf8 ( ours. path ) . unwrap ( ) ) ;
3463+ input. mode ( Some ( FileMode :: from ( ours. mode . try_into ( ) . unwrap ( ) ) ) ) ;
3464+ input. content ( Some ( & ours_content) ) ;
3465+ ours_input = Some ( input) ;
3466+ } else {
3467+ ours_input = None ;
3468+ }
3469+ if let Some ( theirs) = conflict. their {
3470+ theirs_blob = repo
3471+ . find_blob ( theirs. id . clone ( ) )
3472+ . expect ( "failed to find blob of index entry to make MergeFileInput" ) ;
3473+ theirs_content = theirs_blob. content ( ) ;
3474+ let mut input = MergeFileInput :: new ( ) ;
3475+ input. path ( String :: from_utf8 ( theirs. path ) . unwrap ( ) ) ;
3476+ input. mode ( Some ( FileMode :: from ( theirs. mode . try_into ( ) . unwrap ( ) ) ) ) ;
3477+ input. content ( Some ( & theirs_content) ) ;
3478+ theirs_input = Some ( input) ;
3479+ } else {
3480+ theirs_input = None ;
3481+ }
3482+
34603483 let merge_file_result = repo
34613484 . merge_file (
3462- conflict . ancestor . as_ref ( ) ,
3463- conflict . our . as_ref ( ) ,
3464- conflict . their . as_ref ( ) ,
3485+ ancestor_input . as_ref ( ) ,
3486+ ours_input . as_ref ( ) ,
3487+ theirs_input . as_ref ( ) ,
34653488 None ,
34663489 )
34673490 . unwrap ( ) ;
0 commit comments