@@ -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()`.
@@ -3639,4 +3668,41 @@ mod tests {
3639
3668
3640
3669
assert ! ( !config. get_bool( "commit.gpgsign" ) . unwrap( ) ) ;
3641
3670
}
3671
+
3672
+ #[ test]
3673
+ fn smoke_merge_analysis_for_ref ( ) -> Result < ( ) , crate :: Error > {
3674
+ let ( _td, repo) = graph_repo_init ( ) ;
3675
+
3676
+ // Set up this repo state:
3677
+ // * second (their-branch)
3678
+ // * initial (HEAD -> main)
3679
+ //
3680
+ // We expect that their-branch can be fast-forward merged into main.
3681
+
3682
+ // git checkout --detach HEAD
3683
+ let head_commit = repo. head ( ) ?. peel_to_commit ( ) ?;
3684
+ repo. set_head_detached ( head_commit. id ( ) ) ?;
3685
+
3686
+ // git branch their-branch HEAD
3687
+ let their_branch = repo. branch ( "their-branch" , & head_commit, false ) ?;
3688
+
3689
+ // git branch -f main HEAD~
3690
+ let mut parents_iter = head_commit. parents ( ) ;
3691
+ let parent = parents_iter. next ( ) . unwrap ( ) ;
3692
+ assert ! ( parents_iter. next( ) . is_none( ) ) ;
3693
+
3694
+ let main = repo. branch ( "main" , & parent, true ) ?;
3695
+
3696
+ // git checkout main
3697
+ repo. set_head ( main. get ( ) . name ( ) . expect ( "should be utf-8" ) ) ?;
3698
+
3699
+ let ( merge_analysis, _merge_preference) = repo. merge_analysis_for_ref (
3700
+ main. get ( ) ,
3701
+ & [ & repo. reference_to_annotated_commit ( their_branch. get ( ) ) ?] ,
3702
+ ) ?;
3703
+
3704
+ assert ! ( merge_analysis. contains( crate :: MergeAnalysis :: ANALYSIS_FASTFORWARD ) ) ;
3705
+
3706
+ Ok ( ( ) )
3707
+ }
3642
3708
}
0 commit comments