* Do we have another file with a pathname that is a proper * subset of the name we're trying to add? * * That is, is there another file in the index with a path * that matches a sub-directory in the given entry? */
| 1109 | * that matches a sub-directory in the given entry? |
| 1110 | */ |
| 1111 | static int has_dir_name(struct index_state *istate, |
| 1112 | const struct cache_entry *ce, int pos, int ok_to_replace) |
| 1113 | { |
| 1114 | int retval = 0; |
| 1115 | int stage = ce_stage(ce); |
| 1116 | const char *name = ce->name; |
| 1117 | const char *slash = name + ce_namelen(ce); |
| 1118 | size_t len_eq_last; |
| 1119 | int cmp_last = 0; |
| 1120 | |
| 1121 | /* |
| 1122 | * We are frequently called during an iteration on a sorted |
| 1123 | * list of pathnames and while building a new index. Therefore, |
| 1124 | * there is a high probability that this entry will eventually |
| 1125 | * be appended to the index, rather than inserted in the middle. |
| 1126 | * If we can confirm that, we can avoid binary searches on the |
| 1127 | * components of the pathname. |
| 1128 | * |
| 1129 | * Compare the entry's full path with the last path in the index. |
| 1130 | */ |
| 1131 | if (!istate->cache_nr) |
| 1132 | return 0; |
| 1133 | |
| 1134 | cmp_last = strcmp_offset(name, |
| 1135 | istate->cache[istate->cache_nr - 1]->name, |
| 1136 | &len_eq_last); |
| 1137 | if (cmp_last > 0 && name[len_eq_last] != '/') |
| 1138 | /* |
| 1139 | * The entry sorts AFTER the last one in the |
| 1140 | * index and their paths have no common prefix, |
| 1141 | * so there cannot be a F/D conflict. |
| 1142 | */ |
| 1143 | return 0; |
| 1144 | |
| 1145 | for (;;) { |
| 1146 | size_t len; |
| 1147 | |
| 1148 | for (;;) { |
| 1149 | if (*--slash == '/') |
| 1150 | break; |
| 1151 | if (slash <= ce->name) |
| 1152 | return retval; |
| 1153 | } |
| 1154 | len = slash - name; |
| 1155 | |
| 1156 | pos = index_name_stage_pos(istate, name, len, stage, EXPAND_SPARSE); |
| 1157 | if (pos >= 0) { |
| 1158 | /* |
| 1159 | * Found one, but not so fast. This could |
| 1160 | * be a marker that says "I was here, but |
| 1161 | * I am being removed". Such an entry is |
| 1162 | * not a part of the resulting tree, and |
| 1163 | * it is Ok to have a directory at the same |
| 1164 | * path. |
| 1165 | */ |
| 1166 | if (!(istate->cache[pos]->ce_flags & CE_REMOVE)) { |
| 1167 | retval = -1; |
| 1168 | if (!ok_to_replace) |
no test coverage detected