@@ -1964,6 +1964,35 @@ impl Repository {
1964
1964
}
1965
1965
}
1966
1966
1967
+ /// Analyzes the given branch(es) and determines the opportunities for
1968
+ /// merging them into a reference.
1969
+ pub fn merge_analysis_for_ref (
1970
+ & self ,
1971
+ our_ref : & Reference < ' _ > ,
1972
+ their_heads : & [ & AnnotatedCommit < ' _ > ] ,
1973
+ ) -> Result < ( MergeAnalysis , MergePreference ) , Error > {
1974
+ unsafe {
1975
+ let mut raw_merge_analysis = 0 as raw:: git_merge_analysis_t ;
1976
+ let mut raw_merge_preference = 0 as raw:: git_merge_preference_t ;
1977
+ let mut their_heads = their_heads
1978
+ . iter ( )
1979
+ . map ( |v| v. raw ( ) as * const _ )
1980
+ . collect :: < Vec < _ > > ( ) ;
1981
+ try_call ! ( raw:: git_merge_analysis_for_ref(
1982
+ & mut raw_merge_analysis,
1983
+ & mut raw_merge_preference,
1984
+ self . raw,
1985
+ our_ref. raw( ) ,
1986
+ their_heads. as_mut_ptr( ) as * mut _,
1987
+ their_heads. len( )
1988
+ ) ) ;
1989
+ Ok ( (
1990
+ MergeAnalysis :: from_bits_truncate ( raw_merge_analysis as u32 ) ,
1991
+ MergePreference :: from_bits_truncate ( raw_merge_preference as u32 ) ,
1992
+ ) )
1993
+ }
1994
+ }
1995
+
1967
1996
/// Initializes a rebase operation to rebase the changes in `branch`
1968
1997
/// relative to `upstream` onto another branch. To begin the rebase process,
1969
1998
/// call `next()`.
@@ -3621,4 +3650,42 @@ mod tests {
3621
3650
// reverting twice restores `foo` file
3622
3651
assert ! ( foo_file. exists( ) ) ;
3623
3652
}
3653
+
3654
+ #[ test]
3655
+ #[ allow( warnings) ]
3656
+ fn smoke_merge_analysis_for_ref ( ) -> Result < ( ) , crate :: Error > {
3657
+ let ( _td, repo) = graph_repo_init ( ) ;
3658
+
3659
+ // Set up this repo state:
3660
+ // * second (their-branch)
3661
+ // * initial (HEAD -> main)
3662
+ //
3663
+ // We expect that their-branch can be fast-forward merged into main.
3664
+
3665
+ // git checkout --detach HEAD
3666
+ let head_commit = repo. head ( ) ?. peel_to_commit ( ) ?;
3667
+ repo. set_head_detached ( head_commit. id ( ) ) ?;
3668
+
3669
+ // git branch their-branch HEAD
3670
+ let their_branch = repo. branch ( "their-branch" , & head_commit, false ) ?;
3671
+
3672
+ // git branch -f main HEAD~
3673
+ let mut parents_iter = head_commit. parents ( ) ;
3674
+ let parent = parents_iter. next ( ) . unwrap ( ) ;
3675
+ assert ! ( parents_iter. next( ) . is_none( ) ) ;
3676
+
3677
+ let main = repo. branch ( "main" , & parent, true ) ?;
3678
+
3679
+ // git checkout main
3680
+ repo. set_head ( main. name ( ) ?. unwrap ( ) ) ;
3681
+
3682
+ let ( merge_analysis, merge_preference) = repo. merge_analysis_for_ref (
3683
+ main. get ( ) ,
3684
+ & [ & repo. reference_to_annotated_commit ( their_branch. get ( ) ) ?] ,
3685
+ ) ?;
3686
+
3687
+ assert ! ( merge_analysis. contains( crate :: MergeAnalysis :: ANALYSIS_FASTFORWARD ) ) ;
3688
+
3689
+ Ok ( ( ) )
3690
+ }
3624
3691
}
0 commit comments