@@ -25,7 +25,7 @@ static void add_merge_entry(struct merge_list *entry)
25
25
merge_result_end = & entry -> next ;
26
26
}
27
27
28
- 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 );
29
29
30
30
static const char * explanation (struct merge_list * entry )
31
31
{
@@ -190,41 +190,35 @@ static void resolve(const struct traverse_info *info, struct name_entry *ours, s
190
190
add_merge_entry (final );
191
191
}
192
192
193
- 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 )
194
195
{
195
196
char * newbase ;
196
197
struct name_entry * p ;
197
198
struct tree_desc t [3 ];
198
199
void * buf0 , * buf1 , * buf2 ;
199
200
200
- p = n ;
201
- if (!p -> mode ) {
202
- p ++ ;
203
- if (!p -> mode )
204
- p ++ ;
201
+ for (p = n ; p < n + 3 ; p ++ ) {
202
+ if (p -> mode && S_ISDIR (p -> mode ))
203
+ break ;
205
204
}
206
- if (!S_ISDIR (p -> mode ))
207
- return 0 ;
208
- /*
209
- * NEEDSWORK: this is broken. The path can originally be a file
210
- * and then one side may have turned it into a directory, in which
211
- * case we return and let the three-way merge as if the tree were
212
- * a regular file. If the path that was originally a tree is
213
- * now a file in either branch, fill_tree_descriptor() below will
214
- * die when fed a blob sha1.
215
- */
205
+ if (n + 3 <= p )
206
+ return ; /* there is no tree here */
216
207
217
208
newbase = traverse_path (info , p );
218
- buf0 = fill_tree_descriptor (t + 0 , n [0 ].sha1 );
219
- buf1 = fill_tree_descriptor (t + 1 , n [1 ].sha1 );
220
- buf2 = fill_tree_descriptor (t + 2 , n [2 ].sha1 );
221
- 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 );
222
217
223
218
free (buf0 );
224
219
free (buf1 );
225
220
free (buf2 );
226
221
free (newbase );
227
- return 1 ;
228
222
}
229
223
230
224
@@ -247,18 +241,26 @@ static struct merge_list *link_entry(unsigned stage, const struct traverse_info
247
241
static void unresolved (const struct traverse_info * info , struct name_entry n [3 ])
248
242
{
249
243
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
+ }
252
+
253
+ unresolved_directory (info , n , dirmask && (dirmask != mask ));
250
254
251
- if (unresolved_directory ( info , n ) )
255
+ if (dirmask == mask )
252
256
return ;
253
257
254
- /*
255
- * Do them in reverse order so that the resulting link
256
- * list has the stages in order - link_entry adds new
257
- * links at the front.
258
- */
259
- entry = link_entry (3 , info , n + 2 , entry );
260
- entry = link_entry (2 , info , n + 1 , entry );
261
- 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 );
262
264
263
265
add_merge_entry (entry );
264
266
}
@@ -329,15 +331,21 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s
329
331
return mask ;
330
332
}
331
333
332
- 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 )
333
335
{
334
336
struct traverse_info info ;
335
337
336
338
setup_traverse_info (& info , base );
339
+ info .data = & df_conflict ;
337
340
info .fn = threeway_callback ;
338
341
traverse_trees (3 , t , & info );
339
342
}
340
343
344
+ static void merge_trees (struct tree_desc t [3 ], const char * base )
345
+ {
346
+ merge_trees_recursive (t , base , 0 );
347
+ }
348
+
341
349
static void * get_tree_descriptor (struct tree_desc * desc , const char * rev )
342
350
{
343
351
unsigned char sha1 [20 ];
0 commit comments