@@ -126,18 +126,109 @@ static inline int call_unpack_fn(struct cache_entry **src, struct unpack_trees_o
126
126
return ret ;
127
127
}
128
128
129
- static int unpack_index_entry (struct cache_entry * ce , struct unpack_trees_options * o )
129
+ static void mark_ce_used (struct cache_entry * ce , struct unpack_trees_options * o )
130
+ {
131
+ ce -> ce_flags |= CE_UNPACKED ;
132
+
133
+ if (o -> cache_bottom < o -> src_index -> cache_nr &&
134
+ o -> src_index -> cache [o -> cache_bottom ] == ce ) {
135
+ int bottom = o -> cache_bottom ;
136
+ while (bottom < o -> src_index -> cache_nr &&
137
+ o -> src_index -> cache [bottom ]-> ce_flags & CE_UNPACKED )
138
+ bottom ++ ;
139
+ o -> cache_bottom = bottom ;
140
+ }
141
+ }
142
+
143
+ static void mark_all_ce_unused (struct index_state * index )
144
+ {
145
+ int i ;
146
+ for (i = 0 ; i < index -> cache_nr ; i ++ )
147
+ index -> cache [i ]-> ce_flags &= ~CE_UNPACKED ;
148
+ }
149
+
150
+ static int locate_in_src_index (struct cache_entry * ce ,
151
+ struct unpack_trees_options * o )
152
+ {
153
+ struct index_state * index = o -> src_index ;
154
+ int len = ce_namelen (ce );
155
+ int pos = index_name_pos (index , ce -> name , len );
156
+ if (pos < 0 )
157
+ pos = -1 - pos ;
158
+ return pos ;
159
+ }
160
+
161
+ /*
162
+ * We call unpack_index_entry() with an unmerged cache entry
163
+ * only in diff-index, and it wants a single callback. Skip
164
+ * the other unmerged entry with the same name.
165
+ */
166
+ static void mark_ce_used_same_name (struct cache_entry * ce ,
167
+ struct unpack_trees_options * o )
168
+ {
169
+ struct index_state * index = o -> src_index ;
170
+ int len = ce_namelen (ce );
171
+ int pos ;
172
+
173
+ for (pos = locate_in_src_index (ce , o ); pos < index -> cache_nr ; pos ++ ) {
174
+ struct cache_entry * next = index -> cache [pos ];
175
+ if (len != ce_namelen (next ) ||
176
+ memcmp (ce -> name , next -> name , len ))
177
+ break ;
178
+ mark_ce_used (next , o );
179
+ }
180
+ }
181
+
182
+ static struct cache_entry * next_cache_entry (struct unpack_trees_options * o )
183
+ {
184
+ const struct index_state * index = o -> src_index ;
185
+ int pos = o -> cache_bottom ;
186
+
187
+ while (pos < index -> cache_nr ) {
188
+ struct cache_entry * ce = index -> cache [pos ];
189
+ if (!(ce -> ce_flags & CE_UNPACKED ))
190
+ return ce ;
191
+ pos ++ ;
192
+ }
193
+ return NULL ;
194
+ }
195
+
196
+ static void add_same_unmerged (struct cache_entry * ce ,
197
+ struct unpack_trees_options * o )
198
+ {
199
+ struct index_state * index = o -> src_index ;
200
+ int len = ce_namelen (ce );
201
+ int pos = index_name_pos (index , ce -> name , len );
202
+
203
+ if (0 <= pos )
204
+ die ("programming error in a caller of mark_ce_used_same_name" );
205
+ for (pos = - pos - 1 ; pos < index -> cache_nr ; pos ++ ) {
206
+ struct cache_entry * next = index -> cache [pos ];
207
+ if (len != ce_namelen (next ) ||
208
+ memcmp (ce -> name , next -> name , len ))
209
+ break ;
210
+ add_entry (o , next , 0 , 0 );
211
+ mark_ce_used (next , o );
212
+ }
213
+ }
214
+
215
+ static int unpack_index_entry (struct cache_entry * ce ,
216
+ struct unpack_trees_options * o )
130
217
{
131
218
struct cache_entry * src [5 ] = { ce , NULL , };
219
+ int ret ;
132
220
133
- o -> pos ++ ;
221
+ mark_ce_used ( ce , o ) ;
134
222
if (ce_stage (ce )) {
135
223
if (o -> skip_unmerged ) {
136
224
add_entry (o , ce , 0 , 0 );
137
225
return 0 ;
138
226
}
139
227
}
140
- return call_unpack_fn (src , o );
228
+ ret = call_unpack_fn (src , o );
229
+ if (ce_stage (ce ))
230
+ mark_ce_used_same_name (ce , o );
231
+ return ret ;
141
232
}
142
233
143
234
static int traverse_trees_recursive (int n , unsigned long dirmask , unsigned long df_conflicts , struct name_entry * names , struct traverse_info * info )
@@ -212,6 +303,20 @@ static int compare_entry(const struct cache_entry *ce, const struct traverse_inf
212
303
return ce_namelen (ce ) > traverse_path_len (info , n );
213
304
}
214
305
306
+ static int ce_in_traverse_path (const struct cache_entry * ce ,
307
+ const struct traverse_info * info )
308
+ {
309
+ if (!info -> prev )
310
+ return 1 ;
311
+ if (do_compare_entry (ce , info -> prev , & info -> name ))
312
+ return 0 ;
313
+ /*
314
+ * If ce (blob) is the same name as the path (which is a tree
315
+ * we will be descending into), it won't be inside it.
316
+ */
317
+ return (info -> pathlen < ce_namelen (ce ));
318
+ }
319
+
215
320
static struct cache_entry * create_ce_entry (const struct traverse_info * info , const struct name_entry * n , int stage )
216
321
{
217
322
int len = traverse_path_len (info , n );
@@ -300,23 +405,27 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
300
405
301
406
/* Are we supposed to look at the index too? */
302
407
if (o -> merge ) {
303
- while (o -> pos < o -> src_index -> cache_nr ) {
304
- struct cache_entry * ce = o -> src_index -> cache [o -> pos ];
305
- int cmp = compare_entry (ce , info , p );
408
+ while (1 ) {
409
+ struct cache_entry * ce = next_cache_entry (o );
410
+ int cmp ;
411
+ if (!ce )
412
+ break ;
413
+ cmp = compare_entry (ce , info , p );
306
414
if (cmp < 0 ) {
307
415
if (unpack_index_entry (ce , o ) < 0 )
308
416
return unpack_failed (o , NULL );
309
417
continue ;
310
418
}
311
419
if (!cmp ) {
312
- o -> pos ++ ;
313
420
if (ce_stage (ce )) {
314
421
/*
315
- * If we skip unmerged index entries, we'll skip this
316
- * entry *and* the tree entries associated with it!
422
+ * If we skip unmerged index
423
+ * entries, we'll skip this
424
+ * entry *and* the tree
425
+ * entries associated with it!
317
426
*/
318
427
if (o -> skip_unmerged ) {
319
- add_entry ( o , ce , 0 , 0 );
428
+ add_same_unmerged ( ce , o );
320
429
return mask ;
321
430
}
322
431
}
@@ -329,6 +438,13 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
329
438
if (unpack_nondirectories (n , mask , dirmask , src , names , info ) < 0 )
330
439
return -1 ;
331
440
441
+ if (src [0 ]) {
442
+ if (ce_stage (src [0 ]))
443
+ mark_ce_used_same_name (src [0 ], o );
444
+ else
445
+ mark_ce_used (src [0 ], o );
446
+ }
447
+
332
448
/* Now handle any directories.. */
333
449
if (dirmask ) {
334
450
unsigned long conflicts = mask & ~dirmask ;
@@ -345,11 +461,13 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
345
461
matches = cache_tree_matches_traversal (o -> src_index -> cache_tree ,
346
462
names , info );
347
463
/*
348
- * Everything under the name matches. Adjust o->pos to
349
- * skip the entire hierarchy.
464
+ * Everything under the name matches; skip the
465
+ * entire hierarchy. diff_index_cached codepath
466
+ * special cases D/F conflicts in such a way that
467
+ * it does not do any look-ahead, so this is safe.
350
468
*/
351
469
if (matches ) {
352
- o -> pos += matches ;
470
+ o -> cache_bottom += matches ;
353
471
return mask ;
354
472
}
355
473
}
@@ -382,11 +500,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
382
500
383
501
memset (& o -> result , 0 , sizeof (o -> result ));
384
502
o -> result .initialized = 1 ;
385
- if (o -> src_index ) {
386
- o -> result .timestamp .sec = o -> src_index -> timestamp .sec ;
387
- o -> result .timestamp .nsec = o -> src_index -> timestamp .nsec ;
388
- }
503
+ o -> result .timestamp .sec = o -> src_index -> timestamp .sec ;
504
+ o -> result .timestamp .nsec = o -> src_index -> timestamp .nsec ;
389
505
o -> merge_size = len ;
506
+ mark_all_ce_unused (o -> src_index );
390
507
391
508
if (!dfc )
392
509
dfc = xcalloc (1 , cache_entry_size (0 ));
@@ -400,18 +517,38 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
400
517
info .fn = unpack_callback ;
401
518
info .data = o ;
402
519
520
+ if (o -> prefix ) {
521
+ /*
522
+ * Unpack existing index entries that sort before the
523
+ * prefix the tree is spliced into. Note that o->merge
524
+ * is always true in this case.
525
+ */
526
+ while (1 ) {
527
+ struct cache_entry * ce = next_cache_entry (o );
528
+ if (!ce )
529
+ break ;
530
+ if (ce_in_traverse_path (ce , & info ))
531
+ break ;
532
+ if (unpack_index_entry (ce , o ) < 0 )
533
+ goto return_failed ;
534
+ }
535
+ }
536
+
403
537
if (traverse_trees (len , t , & info ) < 0 )
404
- return unpack_failed ( o , NULL ) ;
538
+ goto return_failed ;
405
539
}
406
540
407
541
/* Any left-over entries in the index? */
408
542
if (o -> merge ) {
409
- while (o -> pos < o -> src_index -> cache_nr ) {
410
- struct cache_entry * ce = o -> src_index -> cache [o -> pos ];
543
+ while (1 ) {
544
+ struct cache_entry * ce = next_cache_entry (o );
545
+ if (!ce )
546
+ break ;
411
547
if (unpack_index_entry (ce , o ) < 0 )
412
- return unpack_failed ( o , NULL ) ;
548
+ goto return_failed ;
413
549
}
414
550
}
551
+ mark_all_ce_unused (o -> src_index );
415
552
416
553
if (o -> trivial_merges_only && o -> nontrivial_merge )
417
554
return unpack_failed (o , "Merge requires file-level merging" );
@@ -421,6 +558,10 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
421
558
if (o -> dst_index )
422
559
* o -> dst_index = o -> result ;
423
560
return ret ;
561
+
562
+ return_failed :
563
+ mark_all_ce_unused (o -> src_index );
564
+ return unpack_failed (o , NULL );
424
565
}
425
566
426
567
/* Here come the merge functions */
@@ -522,20 +663,24 @@ static int verify_clean_subdirectory(struct cache_entry *ce, const char *action,
522
663
* in that directory.
523
664
*/
524
665
namelen = strlen (ce -> name );
525
- for (i = o -> pos ; i < o -> src_index -> cache_nr ; i ++ ) {
666
+ for (i = locate_in_src_index (ce , o );
667
+ i < o -> src_index -> cache_nr ;
668
+ i ++ ) {
526
669
struct cache_entry * ce2 = o -> src_index -> cache [i ];
527
670
int len = ce_namelen (ce2 );
528
671
if (len < namelen ||
529
672
strncmp (ce -> name , ce2 -> name , namelen ) ||
530
673
ce2 -> name [namelen ] != '/' )
531
674
break ;
532
675
/*
533
- * ce2->name is an entry in the subdirectory.
676
+ * ce2->name is an entry in the subdirectory to be
677
+ * removed.
534
678
*/
535
679
if (!ce_stage (ce2 )) {
536
680
if (verify_uptodate (ce2 , o ))
537
681
return -1 ;
538
682
add_entry (o , ce2 , CE_REMOVE , 0 );
683
+ mark_ce_used (ce2 , o );
539
684
}
540
685
cnt ++ ;
541
686
}
@@ -591,7 +736,6 @@ static int verify_absent(struct cache_entry *ce, const char *action,
591
736
return 0 ;
592
737
593
738
if (!lstat (ce -> name , & st )) {
594
- int ret ;
595
739
int dtype = ce_to_dtype (ce );
596
740
struct cache_entry * result ;
597
741
@@ -619,28 +763,8 @@ static int verify_absent(struct cache_entry *ce, const char *action,
619
763
* files that are in "foo/" we would lose
620
764
* them.
621
765
*/
622
- ret = verify_clean_subdirectory (ce , action , o );
623
- if (ret < 0 )
624
- return ret ;
625
-
626
- /*
627
- * If this removed entries from the index,
628
- * what that means is:
629
- *
630
- * (1) the caller unpack_callback() saw path/foo
631
- * in the index, and it has not removed it because
632
- * it thinks it is handling 'path' as blob with
633
- * D/F conflict;
634
- * (2) we will return "ok, we placed a merged entry
635
- * in the index" which would cause o->pos to be
636
- * incremented by one;
637
- * (3) however, original o->pos now has 'path/foo'
638
- * marked with "to be removed".
639
- *
640
- * We need to increment it by the number of
641
- * deleted entries here.
642
- */
643
- o -> pos += ret ;
766
+ if (verify_clean_subdirectory (ce , action , o ) < 0 )
767
+ return -1 ;
644
768
return 0 ;
645
769
}
646
770
0 commit comments