@@ -901,6 +901,34 @@ static int has_file_name(struct index_state *istate,
901901 return retval ;
902902}
903903
904+ /*
905+ * Like strcmp(), but also return the offset of the first change.
906+ */
907+ int strcmp_offset (const char * s1_in , const char * s2_in , int * first_change )
908+ {
909+ const unsigned char * s1 = (const unsigned char * )s1_in ;
910+ const unsigned char * s2 = (const unsigned char * )s2_in ;
911+ int diff = 0 ;
912+ int k ;
913+
914+ * first_change = 0 ;
915+ for (k = 0 ; s1 [k ]; k ++ )
916+ if ((diff = (s1 [k ] - s2 [k ])))
917+ goto found_it ;
918+ if (!s2 [k ])
919+ return 0 ;
920+ diff = -1 ;
921+
922+ found_it :
923+ * first_change = k ;
924+ if (diff > 0 )
925+ return 1 ;
926+ else if (diff < 0 )
927+ return -1 ;
928+ else
929+ return 0 ;
930+ }
931+
904932/*
905933 * Do we have another file with a pathname that is a proper
906934 * subset of the name we're trying to add?
@@ -912,6 +940,21 @@ static int has_dir_name(struct index_state *istate,
912940 int stage = ce_stage (ce );
913941 const char * name = ce -> name ;
914942 const char * slash = name + ce_namelen (ce );
943+ int len_eq_last ;
944+ int cmp_last = 0 ;
945+
946+ if (istate -> cache_nr > 0 ) {
947+ /*
948+ * Compare the entry's full path with the last path in the index.
949+ * If it sorts AFTER the last entry in the index and they have no
950+ * common prefix, then there cannot be any F/D name conflicts.
951+ */
952+ cmp_last = strcmp_offset (name ,
953+ istate -> cache [istate -> cache_nr - 1 ]-> name ,
954+ & len_eq_last );
955+ if (cmp_last > 0 && len_eq_last == 0 )
956+ return retval ;
957+ }
915958
916959 for (;;) {
917960 int len ;
@@ -924,6 +967,24 @@ static int has_dir_name(struct index_state *istate,
924967 }
925968 len = slash - name ;
926969
970+ if (cmp_last > 0 ) {
971+ /*
972+ * If this part of the directory prefix (including the trailing
973+ * slash) already appears in the path of the last entry in the
974+ * index, then we cannot also have a file with this prefix (or
975+ * any parent directory prefix).
976+ */
977+ if (len + 1 <= len_eq_last )
978+ return retval ;
979+ /*
980+ * If this part of the directory prefix (excluding the trailing
981+ * slash) is longer than the known equal portions, then this part
982+ * of the prefix cannot collide with a file. Go on to the parent.
983+ */
984+ if (len > len_eq_last )
985+ continue ;
986+ }
987+
927988 pos = index_name_stage_pos (istate , name , len , stage );
928989 if (pos >= 0 ) {
929990 /*
@@ -1015,7 +1076,16 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e
10151076
10161077 if (!(option & ADD_CACHE_KEEP_CACHE_TREE ))
10171078 cache_tree_invalidate_path (istate , ce -> name );
1018- pos = index_name_stage_pos (istate , ce -> name , ce_namelen (ce ), ce_stage (ce ));
1079+
1080+ /*
1081+ * If this entry's path sorts after the last entry in the index,
1082+ * we can avoid searching for it.
1083+ */
1084+ if (istate -> cache_nr > 0 &&
1085+ strcmp (ce -> name , istate -> cache [istate -> cache_nr - 1 ]-> name ) > 0 )
1086+ pos = - istate -> cache_nr - 1 ;
1087+ else
1088+ pos = index_name_stage_pos (istate , ce -> name , ce_namelen (ce ), ce_stage (ce ));
10191089
10201090 /* existing match? Just replace it. */
10211091 if (pos >= 0 ) {
0 commit comments