33#include "xdiff-interface.h"
44#include "blob.h"
55#include "exec_cmd.h"
6- #include "merge-file .h"
6+ #include "merge-blobs .h"
77
88static const char merge_tree_usage [] = "git merge-tree <base-tree> <branch1> <branch2>" ;
9- static int resolve_directories = 1 ;
109
1110struct merge_list {
1211 struct merge_list * next ;
1312 struct merge_list * link ; /* other stages for this object */
1413
15- unsigned int stage : 2 ,
16- flags : 30 ;
14+ unsigned int stage : 2 ;
1715 unsigned int mode ;
1816 const char * path ;
1917 struct blob * blob ;
@@ -27,7 +25,7 @@ static void add_merge_entry(struct merge_list *entry)
2725 merge_result_end = & entry -> next ;
2826}
2927
30- static void merge_trees (struct tree_desc t [3 ], const char * base );
28+ static void merge_trees_recursive (struct tree_desc t [3 ], const char * base , int df_conflict );
3129
3230static const char * explanation (struct merge_list * entry )
3331{
@@ -76,7 +74,7 @@ static void *result(struct merge_list *entry, unsigned long *size)
7674 their = NULL ;
7775 if (entry )
7876 their = entry -> blob ;
79- return merge_file (path , base , our , their , size );
77+ return merge_blobs (path , base , our , their , size );
8078}
8179
8280static void * origin (struct merge_list * entry , unsigned long * size )
@@ -174,52 +172,53 @@ static char *traverse_path(const struct traverse_info *info, const struct name_e
174172 return make_traverse_path (path , info , n );
175173}
176174
177- static void resolve (const struct traverse_info * info , struct name_entry * branch1 , struct name_entry * result )
175+ static void resolve (const struct traverse_info * info , struct name_entry * ours , struct name_entry * result )
178176{
179177 struct merge_list * orig , * final ;
180178 const char * path ;
181179
182- /* If it's already branch1 , don't bother showing it */
183- if (!branch1 )
180+ /* If it's already ours , don't bother showing it */
181+ if (!ours )
184182 return ;
185183
186184 path = traverse_path (info , result );
187- orig = create_entry (2 , branch1 -> mode , branch1 -> sha1 , path );
185+ orig = create_entry (2 , ours -> mode , ours -> sha1 , path );
188186 final = create_entry (0 , result -> mode , result -> sha1 , path );
189187
190188 final -> link = orig ;
191189
192190 add_merge_entry (final );
193191}
194192
195- static int unresolved_directory (const struct traverse_info * info , struct name_entry n [3 ])
193+ static void unresolved_directory (const struct traverse_info * info , struct name_entry n [3 ],
194+ int df_conflict )
196195{
197196 char * newbase ;
198197 struct name_entry * p ;
199198 struct tree_desc t [3 ];
200199 void * buf0 , * buf1 , * buf2 ;
201200
202- if (!resolve_directories )
203- return 0 ;
204- p = n ;
205- if (!p -> mode ) {
206- p ++ ;
207- if (!p -> mode )
208- p ++ ;
201+ for (p = n ; p < n + 3 ; p ++ ) {
202+ if (p -> mode && S_ISDIR (p -> mode ))
203+ break ;
209204 }
210- if (!S_ISDIR (p -> mode ))
211- return 0 ;
205+ if (n + 3 <= p )
206+ return ; /* there is no tree here */
207+
212208 newbase = traverse_path (info , p );
213- buf0 = fill_tree_descriptor (t + 0 , n [0 ].sha1 );
214- buf1 = fill_tree_descriptor (t + 1 , n [1 ].sha1 );
215- buf2 = fill_tree_descriptor (t + 2 , n [2 ].sha1 );
216- merge_trees (t , newbase );
209+
210+ #define ENTRY_SHA1 (e ) (((e)->mode && S_ISDIR((e)->mode)) ? (e)->sha1 : NULL)
211+ buf0 = fill_tree_descriptor (t + 0 , ENTRY_SHA1 (n + 0 ));
212+ buf1 = fill_tree_descriptor (t + 1 , ENTRY_SHA1 (n + 1 ));
213+ buf2 = fill_tree_descriptor (t + 2 , ENTRY_SHA1 (n + 2 ));
214+ #undef ENTRY_SHA1
215+
216+ merge_trees_recursive (t , newbase , df_conflict );
217217
218218 free (buf0 );
219219 free (buf1 );
220220 free (buf2 );
221221 free (newbase );
222- return 1 ;
223222}
224223
225224
@@ -242,18 +241,26 @@ static struct merge_list *link_entry(unsigned stage, const struct traverse_info
242241static void unresolved (const struct traverse_info * info , struct name_entry n [3 ])
243242{
244243 struct merge_list * entry = NULL ;
244+ int i ;
245+ unsigned dirmask = 0 , mask = 0 ;
246+
247+ for (i = 0 ; i < 3 ; i ++ ) {
248+ mask |= (1 << 1 );
249+ if (n [i ].mode && S_ISDIR (n [i ].mode ))
250+ dirmask |= (1 << i );
251+ }
245252
246- if (unresolved_directory (info , n ))
253+ unresolved_directory (info , n , dirmask && (dirmask != mask ));
254+
255+ if (dirmask == mask )
247256 return ;
248257
249- /*
250- * Do them in reverse order so that the resulting link
251- * list has the stages in order - link_entry adds new
252- * links at the front.
253- */
254- entry = link_entry (3 , info , n + 2 , entry );
255- entry = link_entry (2 , info , n + 1 , entry );
256- entry = link_entry (1 , info , n + 0 , entry );
258+ if (n [2 ].mode && !S_ISDIR (n [2 ].mode ))
259+ entry = link_entry (3 , info , n + 2 , entry );
260+ if (n [1 ].mode && !S_ISDIR (n [1 ].mode ))
261+ entry = link_entry (2 , info , n + 1 , entry );
262+ if (n [0 ].mode && !S_ISDIR (n [0 ].mode ))
263+ entry = link_entry (1 , info , n + 0 , entry );
257264
258265 add_merge_entry (entry );
259266}
@@ -292,20 +299,29 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s
292299 /* Same in both? */
293300 if (same_entry (entry + 1 , entry + 2 )) {
294301 if (entry [0 ].sha1 ) {
302+ /* Modified identically */
295303 resolve (info , NULL , entry + 1 );
296304 return mask ;
297305 }
306+ /* "Both added the same" is left unresolved */
298307 }
299308
300309 if (same_entry (entry + 0 , entry + 1 )) {
301310 if (entry [2 ].sha1 && !S_ISDIR (entry [2 ].mode )) {
311+ /* We did not touch, they modified -- take theirs */
302312 resolve (info , entry + 1 , entry + 2 );
303313 return mask ;
304314 }
315+ /*
316+ * If we did not touch a directory but they made it
317+ * into a file, we fall through and unresolved()
318+ * recurses down. Likewise for the opposite case.
319+ */
305320 }
306321
307322 if (same_entry (entry + 0 , entry + 2 )) {
308323 if (entry [1 ].sha1 && !S_ISDIR (entry [1 ].mode )) {
324+ /* We modified, they did not touch -- take ours */
309325 resolve (info , NULL , entry + 1 );
310326 return mask ;
311327 }
@@ -315,15 +331,21 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s
315331 return mask ;
316332}
317333
318- static void merge_trees (struct tree_desc t [3 ], const char * base )
334+ static void merge_trees_recursive (struct tree_desc t [3 ], const char * base , int df_conflict )
319335{
320336 struct traverse_info info ;
321337
322338 setup_traverse_info (& info , base );
339+ info .data = & df_conflict ;
323340 info .fn = threeway_callback ;
324341 traverse_trees (3 , t , & info );
325342}
326343
344+ static void merge_trees (struct tree_desc t [3 ], const char * base )
345+ {
346+ merge_trees_recursive (t , base , 0 );
347+ }
348+
327349static void * get_tree_descriptor (struct tree_desc * desc , const char * rev )
328350{
329351 unsigned char sha1 [20 ];
0 commit comments