@@ -1928,58 +1928,59 @@ static int merge_annotated_commits(
19281928 git_index * * index_out ,
19291929 git_annotated_commit * * base_out ,
19301930 git_repository * repo ,
1931- const git_annotated_commit * our_commit ,
1932- const git_annotated_commit * their_commit ,
1931+ git_annotated_commit * our_commit ,
1932+ git_annotated_commit * their_commit ,
19331933 size_t recursion_level ,
19341934 const git_merge_options * opts );
19351935
1936+ GIT_INLINE (int ) insert_head_ids (
1937+ git_array_oid_t * ids ,
1938+ const git_annotated_commit * annotated_commit )
1939+ {
1940+ git_oid * id ;
1941+ size_t i ;
1942+
1943+ if (annotated_commit -> type == GIT_ANNOTATED_COMMIT_REAL ) {
1944+ id = git_array_alloc (* ids );
1945+ GITERR_CHECK_ALLOC (id );
1946+
1947+ git_oid_cpy (id , git_commit_id (annotated_commit -> commit ));
1948+ } else {
1949+ for (i = 0 ; i < annotated_commit -> parents .size ; i ++ ) {
1950+ id = git_array_alloc (* ids );
1951+ GITERR_CHECK_ALLOC (id );
1952+
1953+ git_oid_cpy (id , & annotated_commit -> parents .ptr [i ]);
1954+ }
1955+ }
1956+
1957+ return 0 ;
1958+ }
1959+
19361960static int create_virtual_base (
19371961 git_annotated_commit * * out ,
19381962 git_repository * repo ,
1939- const git_annotated_commit * one ,
1940- const git_annotated_commit * two ,
1963+ git_annotated_commit * one ,
1964+ git_annotated_commit * two ,
19411965 size_t recursion_level )
19421966{
1967+ git_annotated_commit * result = NULL ;
19431968 git_index * index = NULL ;
1944- git_tree * tree = NULL ;
1945- git_commit * commit = NULL ;
1946- git_oid id , tree_id ;
1947- const git_commit * parents [2 ];
1948- git_signature * signature = NULL ;
1949- int error ;
1950-
1951- parents [0 ] = one -> commit ;
1952- parents [1 ] = two -> commit ;
1953-
1954- if ((error = merge_annotated_commits (& index , NULL , repo , one , two ,
1955- recursion_level + 1 , NULL )) < 0 ||
1956- (error = git_index_write_tree_to (& tree_id , index , repo )) < 0 ||
1957- (error = git_tree_lookup (& tree , repo , & tree_id )) < 0 ||
1958- (error = git_signature_now (& signature , "Virtual" , "virtual" )) < 0 ||
1959- (error = git_commit_create (& id , repo , NULL , signature , signature ,
1960- NULL , "virtual merged tree" , tree , 2 , parents )) < 0 ||
1961- (error = git_commit_lookup (& commit , repo , & id )) < 0 )
1962- goto done ;
19631969
1964- error = git_annotated_commit_from_commit (out , commit );
1970+ result = git__calloc (1 , sizeof (git_annotated_commit ));
1971+ GITERR_CHECK_ALLOC (result );
19651972
1966- done :
1967- git_commit_free (commit );
1968- git_tree_free (tree );
1969- git_index_free (index );
1970- git_signature_free (signature );
1973+ if ((merge_annotated_commits (& index , NULL , repo , one , two ,
1974+ recursion_level + 1 , NULL )) < 0 )
1975+ return -1 ;
19711976
1972- return error ;
1973- }
1977+ result -> type = GIT_ANNOTATED_COMMIT_VIRTUAL ;
1978+ result -> index = index ;
19741979
1975- GIT_INLINE (int ) insert_head_ids (
1976- git_array_oid_t * ids ,
1977- const git_annotated_commit * annotated_commit )
1978- {
1979- git_oid * id = git_array_alloc (* ids );
1980- GITERR_CHECK_ALLOC (id );
1980+ insert_head_ids (& result -> parents , one );
1981+ insert_head_ids (& result -> parents , two );
19811982
1982- git_oid_cpy ( id , git_commit_id ( annotated_commit -> commit )) ;
1983+ * out = result ;
19831984 return 0 ;
19841985}
19851986
@@ -2039,35 +2040,59 @@ static int compute_base(
20392040 return error ;
20402041}
20412042
2043+ static int iterator_for_annotated_commit (
2044+ git_iterator * * out ,
2045+ git_annotated_commit * commit )
2046+ {
2047+ git_iterator_options opts = GIT_ITERATOR_OPTIONS_INIT ;
2048+ int error ;
2049+
2050+ opts .flags = GIT_ITERATOR_DONT_IGNORE_CASE ;
2051+
2052+ if (commit == NULL ) {
2053+ error = git_iterator_for_nothing (out , & opts );
2054+ } else if (commit -> type == GIT_ANNOTATED_COMMIT_VIRTUAL ) {
2055+ error = git_iterator_for_index (out , commit -> index , & opts );
2056+ } else {
2057+ if (!commit -> tree &&
2058+ (error = git_commit_tree (& commit -> tree , commit -> commit )) < 0 )
2059+ goto done ;
2060+
2061+ error = git_iterator_for_tree (out , commit -> tree , & opts );
2062+ }
2063+
2064+ done :
2065+ return error ;
2066+ }
2067+
20422068static int merge_annotated_commits (
20432069 git_index * * index_out ,
20442070 git_annotated_commit * * base_out ,
20452071 git_repository * repo ,
2046- const git_annotated_commit * our_commit ,
2047- const git_annotated_commit * their_commit ,
2072+ git_annotated_commit * ours ,
2073+ git_annotated_commit * theirs ,
20482074 size_t recursion_level ,
20492075 const git_merge_options * opts )
20502076{
20512077 git_annotated_commit * base = NULL ;
2052- git_tree * base_tree = NULL , * our_tree = NULL , * their_tree = NULL ;
2078+ git_iterator * base_iter = NULL , * our_iter = NULL , * their_iter = NULL ;
20532079 bool recurse = !opts || !(opts -> flags & GIT_MERGE_NO_RECURSIVE );
20542080 int error ;
20552081
2056- if ((error = compute_base (& base , repo , our_commit , their_commit ,
2057- recurse , recursion_level )) < 0 ) {
2082+ if ((error = compute_base (& base , repo , ours , theirs , recurse ,
2083+ recursion_level )) < 0 ) {
20582084
20592085 if (error != GIT_ENOTFOUND )
20602086 goto done ;
20612087
20622088 giterr_clear ();
2063- } else if ((error = git_commit_tree (& base_tree , base -> commit )) < 0 ) {
2064- goto done ;
2065- }
2089+ }
20662090
2067- if ((error = git_commit_tree (& our_tree , our_commit -> commit )) < 0 ||
2068- (error = git_commit_tree (& their_tree , their_commit -> commit )) < 0 ||
2069- (error = git_merge_trees (index_out , repo , base_tree , our_tree ,
2070- their_tree , opts )) < 0 )
2091+ if ((error = iterator_for_annotated_commit (& base_iter , base )) < 0 ||
2092+ (error = iterator_for_annotated_commit (& our_iter , ours )) < 0 ||
2093+ (error = iterator_for_annotated_commit (& their_iter , theirs )) < 0 ||
2094+ (error = git_merge__iterators (index_out , repo , base_iter , our_iter ,
2095+ their_iter , opts )) < 0 )
20712096 goto done ;
20722097
20732098 if (base_out ) {
@@ -2077,9 +2102,9 @@ static int merge_annotated_commits(
20772102
20782103done :
20792104 git_annotated_commit_free (base );
2080- git_tree_free ( our_tree );
2081- git_tree_free ( their_tree );
2082- git_tree_free ( base_tree );
2105+ git_iterator_free ( base_iter );
2106+ git_iterator_free ( our_iter );
2107+ git_iterator_free ( their_iter );
20832108 return error ;
20842109}
20852110
@@ -2558,14 +2583,13 @@ static int merge_normalize_checkout_opts(
25582583
25592584 out -> checkout_strategy = checkout_strategy ;
25602585
2561- /* TODO: disambiguate between merged common ancestors and no common
2562- * ancestor (although git.git does not!)
2563- */
25642586 if (!out -> ancestor_label ) {
2565- if (ancestor )
2587+ if (ancestor && ancestor -> type == GIT_ANNOTATED_COMMIT_REAL )
25662588 out -> ancestor_label = git_commit_summary (ancestor -> commit );
2567- else
2589+ else if ( ancestor )
25682590 out -> ancestor_label = "merged common ancestors" ;
2591+ else
2592+ out -> ancestor_label = "empty base" ;
25692593 }
25702594
25712595 if (!out -> our_label ) {
@@ -2967,7 +2991,7 @@ int git_merge(
29672991 /* TODO: octopus */
29682992
29692993 if ((error = merge_annotated_commits (& index , & base , repo , our_head ,
2970- their_heads [0 ], 0 , merge_opts )) < 0 ||
2994+ ( git_annotated_commit * ) their_heads [0 ], 0 , merge_opts )) < 0 ||
29712995 (error = git_merge__check_result (repo , index )) < 0 ||
29722996 (error = git_merge__append_conflicts_to_merge_msg (repo , index )) < 0 )
29732997 goto done ;
0 commit comments