@@ -70,7 +70,6 @@ static int entcmp(const char *name1, int dir1, const char *name2, int dir2)
70
70
71
71
static int unpack_trees_rec (struct tree_entry_list * * posns , int len ,
72
72
const char * base , struct unpack_trees_options * o ,
73
- int * indpos ,
74
73
struct tree_entry_list * df_conflict_list )
75
74
{
76
75
int baselen = strlen (base );
@@ -100,7 +99,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
100
99
cache_name = NULL ;
101
100
102
101
/* Check the cache */
103
- if (o -> merge && * indpos < active_nr ) {
102
+ if (o -> merge && o -> pos < active_nr ) {
104
103
/* This is a bit tricky: */
105
104
/* If the index has a subdirectory (with
106
105
* contents) as the first name, it'll get a
@@ -118,7 +117,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
118
117
* file case.
119
118
*/
120
119
121
- cache_name = active_cache [* indpos ]-> name ;
120
+ cache_name = active_cache [o -> pos ]-> name ;
122
121
if (strlen (cache_name ) > baselen &&
123
122
!memcmp (cache_name , base , baselen )) {
124
123
cache_name += baselen ;
@@ -158,8 +157,8 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
158
157
159
158
if (cache_name && !strcmp (cache_name , first )) {
160
159
any_files = 1 ;
161
- src [0 ] = active_cache [* indpos ];
162
- remove_cache_entry_at (* indpos );
160
+ src [0 ] = active_cache [o -> pos ];
161
+ remove_cache_entry_at (o -> pos );
163
162
}
164
163
165
164
for (i = 0 ; i < len ; i ++ ) {
@@ -228,7 +227,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
228
227
#if DBRT_DEBUG > 1
229
228
printf ("Added %d entries\n" , ret );
230
229
#endif
231
- * indpos += ret ;
230
+ o -> pos += ret ;
232
231
} else {
233
232
for (i = 0 ; i < src_size ; i ++ ) {
234
233
if (src [i ]) {
@@ -244,7 +243,7 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
244
243
newbase [baselen + pathlen ] = '/' ;
245
244
newbase [baselen + pathlen + 1 ] = '\0' ;
246
245
if (unpack_trees_rec (subposns , len , newbase , o ,
247
- indpos , df_conflict_list )) {
246
+ df_conflict_list )) {
248
247
retval = -1 ;
249
248
goto leave_directory ;
250
249
}
@@ -375,7 +374,6 @@ static void check_updates(struct cache_entry **src, int nr,
375
374
376
375
int unpack_trees (struct object_list * trees , struct unpack_trees_options * o )
377
376
{
378
- int indpos = 0 ;
379
377
unsigned len = object_list_length (trees );
380
378
struct tree_entry_list * * posns ;
381
379
int i ;
@@ -404,7 +402,7 @@ int unpack_trees(struct object_list *trees, struct unpack_trees_options *o)
404
402
posn = posn -> next ;
405
403
}
406
404
if (unpack_trees_rec (posns , len , o -> prefix ? o -> prefix : "" ,
407
- o , & indpos , & df_conflict_list ))
405
+ o , & df_conflict_list ))
408
406
return -1 ;
409
407
}
410
408
@@ -467,6 +465,64 @@ static void invalidate_ce_path(struct cache_entry *ce)
467
465
cache_tree_invalidate_path (active_cache_tree , ce -> name );
468
466
}
469
467
468
+ static int verify_clean_subdirectory (const char * path , const char * action ,
469
+ struct unpack_trees_options * o )
470
+ {
471
+ /*
472
+ * we are about to extract "path"; we would not want to lose
473
+ * anything in the existing directory there.
474
+ */
475
+ int namelen ;
476
+ int pos , i ;
477
+ struct dir_struct d ;
478
+ char * pathbuf ;
479
+ int cnt = 0 ;
480
+
481
+ /*
482
+ * First let's make sure we do not have a local modification
483
+ * in that directory.
484
+ */
485
+ namelen = strlen (path );
486
+ pos = cache_name_pos (path , namelen );
487
+ if (0 <= pos )
488
+ return cnt ; /* we have it as nondirectory */
489
+ pos = - pos - 1 ;
490
+ for (i = pos ; i < active_nr ; i ++ ) {
491
+ struct cache_entry * ce = active_cache [i ];
492
+ int len = ce_namelen (ce );
493
+ if (len < namelen ||
494
+ strncmp (path , ce -> name , namelen ) ||
495
+ ce -> name [namelen ] != '/' )
496
+ break ;
497
+ /*
498
+ * ce->name is an entry in the subdirectory.
499
+ */
500
+ if (!ce_stage (ce )) {
501
+ verify_uptodate (ce , o );
502
+ ce -> ce_mode = 0 ;
503
+ }
504
+ cnt ++ ;
505
+ }
506
+
507
+ /*
508
+ * Then we need to make sure that we do not lose a locally
509
+ * present file that is not ignored.
510
+ */
511
+ pathbuf = xmalloc (namelen + 2 );
512
+ memcpy (pathbuf , path , namelen );
513
+ strcpy (pathbuf + namelen , "/" );
514
+
515
+ memset (& d , 0 , sizeof (d ));
516
+ if (o -> dir )
517
+ d .exclude_per_dir = o -> dir -> exclude_per_dir ;
518
+ i = read_directory (& d , path , pathbuf , namelen + 1 , NULL );
519
+ if (i )
520
+ die ("Updating '%s' would lose untracked files in it" ,
521
+ path );
522
+ free (pathbuf );
523
+ return cnt ;
524
+ }
525
+
470
526
/*
471
527
* We do not want to remove or overwrite a working tree file that
472
528
* is not tracked, unless it is ignored.
@@ -478,9 +534,62 @@ static void verify_absent(const char *path, const char *action,
478
534
479
535
if (o -> index_only || o -> reset || !o -> update )
480
536
return ;
481
- if (!lstat (path , & st ) && !(o -> dir && excluded (o -> dir , path )))
537
+
538
+ if (!lstat (path , & st )) {
539
+ int cnt ;
540
+
541
+ if (o -> dir && excluded (o -> dir , path ))
542
+ /*
543
+ * path is explicitly excluded, so it is Ok to
544
+ * overwrite it.
545
+ */
546
+ return ;
547
+ if (S_ISDIR (st .st_mode )) {
548
+ /*
549
+ * We are checking out path "foo" and
550
+ * found "foo/." in the working tree.
551
+ * This is tricky -- if we have modified
552
+ * files that are in "foo/" we would lose
553
+ * it.
554
+ */
555
+ cnt = verify_clean_subdirectory (path , action , o );
556
+
557
+ /*
558
+ * If this removed entries from the index,
559
+ * what that means is:
560
+ *
561
+ * (1) the caller unpack_trees_rec() saw path/foo
562
+ * in the index, and it has not removed it because
563
+ * it thinks it is handling 'path' as blob with
564
+ * D/F conflict;
565
+ * (2) we will return "ok, we placed a merged entry
566
+ * in the index" which would cause o->pos to be
567
+ * incremented by one;
568
+ * (3) however, original o->pos now has 'path/foo'
569
+ * marked with "to be removed".
570
+ *
571
+ * We need to increment it by the number of
572
+ * deleted entries here.
573
+ */
574
+ o -> pos += cnt ;
575
+ return ;
576
+ }
577
+
578
+ /*
579
+ * The previous round may already have decided to
580
+ * delete this path, which is in a subdirectory that
581
+ * is being replaced with a blob.
582
+ */
583
+ cnt = cache_name_pos (path , strlen (path ));
584
+ if (0 <= cnt ) {
585
+ struct cache_entry * ce = active_cache [cnt ];
586
+ if (!ce_stage (ce ) && !ce -> ce_mode )
587
+ return ;
588
+ }
589
+
482
590
die ("Untracked working tree file '%s' "
483
591
"would be %s by merge." , path , action );
592
+ }
484
593
}
485
594
486
595
static int merged_entry (struct cache_entry * merge , struct cache_entry * old ,
@@ -525,7 +634,7 @@ static int deleted_entry(struct cache_entry *ce, struct cache_entry *old,
525
634
return 1 ;
526
635
}
527
636
528
- static int keep_entry (struct cache_entry * ce )
637
+ static int keep_entry (struct cache_entry * ce , struct unpack_trees_options * o )
529
638
{
530
639
add_cache_entry (ce , ADD_CACHE_OK_TO_ADD );
531
640
return 1 ;
@@ -682,7 +791,7 @@ int threeway_merge(struct cache_entry **stages,
682
791
if (!head_match || !remote_match ) {
683
792
for (i = 1 ; i < o -> head_idx ; i ++ ) {
684
793
if (stages [i ]) {
685
- keep_entry (stages [i ]);
794
+ keep_entry (stages [i ], o );
686
795
count ++ ;
687
796
break ;
688
797
}
@@ -695,8 +804,8 @@ int threeway_merge(struct cache_entry **stages,
695
804
show_stage_entry (stderr , "remote " , stages [remote_match ]);
696
805
}
697
806
#endif
698
- if (head ) { count += keep_entry (head ); }
699
- if (remote ) { count += keep_entry (remote ); }
807
+ if (head ) { count += keep_entry (head , o ); }
808
+ if (remote ) { count += keep_entry (remote , o ); }
700
809
return count ;
701
810
}
702
811
@@ -713,22 +822,28 @@ int twoway_merge(struct cache_entry **src,
713
822
struct unpack_trees_options * o )
714
823
{
715
824
struct cache_entry * current = src [0 ];
716
- struct cache_entry * oldtree = src [1 ], * newtree = src [2 ];
825
+ struct cache_entry * oldtree = src [1 ];
826
+ struct cache_entry * newtree = src [2 ];
717
827
718
828
if (o -> merge_size != 2 )
719
829
return error ("Cannot do a twoway merge of %d trees" ,
720
830
o -> merge_size );
721
831
832
+ if (oldtree == o -> df_conflict_entry )
833
+ oldtree = NULL ;
834
+ if (newtree == o -> df_conflict_entry )
835
+ newtree = NULL ;
836
+
722
837
if (current ) {
723
838
if ((!oldtree && !newtree ) || /* 4 and 5 */
724
839
(!oldtree && newtree &&
725
840
same (current , newtree )) || /* 6 and 7 */
726
841
(oldtree && newtree &&
727
842
same (oldtree , newtree )) || /* 14 and 15 */
728
843
(oldtree && newtree &&
729
- !same (oldtree , newtree ) && /* 18 and 19*/
844
+ !same (oldtree , newtree ) && /* 18 and 19 */
730
845
same (current , newtree ))) {
731
- return keep_entry (current );
846
+ return keep_entry (current , o );
732
847
}
733
848
else if (oldtree && !newtree && same (current , oldtree )) {
734
849
/* 10 or 11 */
@@ -774,7 +889,7 @@ int bind_merge(struct cache_entry **src,
774
889
if (a && old )
775
890
die ("Entry '%s' overlaps. Cannot bind." , a -> name );
776
891
if (!a )
777
- return keep_entry (old );
892
+ return keep_entry (old , o );
778
893
else
779
894
return merged_entry (a , NULL , o );
780
895
}
@@ -804,7 +919,7 @@ int oneway_merge(struct cache_entry **src,
804
919
ce_match_stat (old , & st , 1 ))
805
920
old -> ce_flags |= htons (CE_UPDATE );
806
921
}
807
- return keep_entry (old );
922
+ return keep_entry (old , o );
808
923
}
809
924
return merged_entry (a , old , o );
810
925
}
0 commit comments