@@ -36,6 +36,78 @@ impl crate::Repository {
3636 . ok_or ( revision:: spec:: parse:: single:: Error :: RangedRev { spec : spec. into ( ) } )
3737 }
3838
39+ /// Obtain the best merge-base between commit `one` and `two`, or fail if there is none.
40+ ///
41+ /// # Performance
42+ /// For repeated calls, prefer [`merge_base_with_cache()`](crate::Repository::merge_base_with_cache()).
43+ /// Also be sure to [set an object cache](crate::Repository::object_cache_size_if_unset) to accelerate repeated commit lookups.
44+ #[ cfg( feature = "revision" ) ]
45+ pub fn merge_base (
46+ & self ,
47+ one : impl Into < gix_hash:: ObjectId > ,
48+ two : impl Into < gix_hash:: ObjectId > ,
49+ ) -> Result < Id < ' _ > , super :: merge_base:: Error > {
50+ use crate :: prelude:: ObjectIdExt ;
51+ let one = one. into ( ) ;
52+ let two = two. into ( ) ;
53+ let cache = self . commit_graph_if_enabled ( ) ?;
54+ let mut graph = self . revision_graph ( cache. as_ref ( ) ) ;
55+ let bases =
56+ gix_revision:: merge_base ( one, & vec ! [ two] , & mut graph) ?. ok_or ( super :: merge_base:: Error :: NotFound {
57+ first : one,
58+ second : two,
59+ } ) ?;
60+ Ok ( bases[ 0 ] . attach ( self ) )
61+ }
62+
63+ /// Obtain the best merge-base between commit `one` and `two`, or fail if there is none, providing a
64+ /// commit-graph `cache` to potentially greatly accelerate the operation.
65+ ///
66+ /// # Performance
67+ /// Be sure to [set an object cache](crate::Repository::object_cache_size_if_unset) to accelerate repeated commit lookups.
68+ #[ cfg( feature = "revision" ) ]
69+ pub fn merge_base_with_cache (
70+ & self ,
71+ one : impl Into < gix_hash:: ObjectId > ,
72+ two : impl Into < gix_hash:: ObjectId > ,
73+ cache : Option < & gix_commitgraph:: Graph > ,
74+ ) -> Result < Id < ' _ > , super :: merge_base_with_cache:: Error > {
75+ use crate :: prelude:: ObjectIdExt ;
76+ let one = one. into ( ) ;
77+ let two = two. into ( ) ;
78+ let mut graph = self . revision_graph ( cache) ;
79+ let bases = gix_revision:: merge_base ( one, & vec ! [ two] , & mut graph) ?. ok_or (
80+ super :: merge_base_with_cache:: Error :: NotFound {
81+ first : one,
82+ second : two,
83+ } ,
84+ ) ?;
85+ Ok ( bases[ 0 ] . attach ( self ) )
86+ }
87+
88+ /// Obtain all merge-bases between commit `one` and `others`, or an empty list if there is none, providing a
89+ /// commit-graph `cache` to potentially greatly accelerate the operation.
90+ ///
91+ /// # Performance
92+ /// Be sure to [set an object cache](crate::Repository::object_cache_size_if_unset) to accelerate repeated commit lookups.
93+ #[ doc( alias = "merge_bases_many" , alias = "git2" ) ]
94+ #[ cfg( feature = "revision" ) ]
95+ pub fn merge_bases_many_with_cache (
96+ & self ,
97+ one : impl Into < gix_hash:: ObjectId > ,
98+ others : & [ gix_hash:: ObjectId ] ,
99+ cache : Option < & gix_commitgraph:: Graph > ,
100+ ) -> Result < Vec < Id < ' _ > > , gix_revision:: merge_base:: Error > {
101+ use crate :: prelude:: ObjectIdExt ;
102+ let one = one. into ( ) ;
103+ let mut graph = self . revision_graph ( cache) ;
104+ Ok ( gix_revision:: merge_base ( one, others, & mut graph) ?
105+ . unwrap_or_default ( )
106+ . into_iter ( )
107+ . map ( |id| id. attach ( self ) )
108+ . collect ( ) )
109+ }
110+
39111 /// Create the baseline for a revision walk by initializing it with the `tips` to start iterating on.
40112 ///
41113 /// It can be configured further before starting the actual walk.
0 commit comments