1052
const struct name_entry *n,
1053
int stage,
1054
struct index_state *istate,
1055
- int is_transient)
1055
+ int is_transient,
1056
+ int is_sparse_directory)
1057
{
1058
size_t len = traverse_path_len(info, tree_entry_len(n));
1059
+ size_t alloc_len = is_sparse_directory ? len + 1 : len;
1060
struct cache_entry *ce =
1061
is_transient ?
1060
- make_empty_transient_cache_entry(len, NULL) :
1061
- make_empty_cache_entry(istate, len);
1062
+ make_empty_transient_cache_entry(alloc_len, NULL) :
1063
+ make_empty_cache_entry(istate, alloc_len);
1064
1065
ce->ce_mode = create_ce_mode(n->mode);
1066
ce->ce_flags = create_ce_flags(stage);
1069
/* len+1 because the cache_entry allocates space for NUL */
1070
make_traverse_path(ce->name, len + 1, info, n->path, n->pathlen);
1071
1072
+ if (is_sparse_directory) {
1073
+ ce->name[len] = '/';
1074
+ ce->name[len + 1] = '\0';
1075
+ ce->ce_namelen++;
1076
+ ce->ce_flags |= CE_SKIP_WORKTREE;
1077
+ }
1078
+
1079
return ce;
1080
}
1081
1094
struct unpack_trees_options *o = info->data;
1095
unsigned long conflicts = info->df_conflicts | dirmask;
1096
1088
- /* Do we have *only* directories? Nothing to do */
1097
if (mask == dirmask && !src[0])
1098
return 0;
1099
1100
+ /*
1101
+ * When we have a sparse directory entry for src[0],
1102
+ * then this isn't necessarily a directory-file conflict.
1103
+ */
1104
+ if (mask == dirmask && src[0] &&
1105
+ S_ISSPARSEDIR(src[0]->ce_mode))
1106
+ conflicts = 0;
1107
+
1108
/*
1109
* Ok, we've filled in up to any potential index entry in src[0],
1110
* now do the rest.
1134
* not stored in the index. otherwise construct the
1135
* cache entry from the index aware logic.
1136
*/
1121
- src[i + o->merge] = create_ce_entry(info, names + i, stage, &o->result, o->merge);
1137
+ src[i + o->merge] = create_ce_entry(info, names + i, stage,
1138
+ &o->result, o->merge,
1139
+ bit & dirmask);
1140
}
1141
1142
if (o->merge) {
1240
return -1;
1241
}
1242
1243
+/*
1244
+ * Given a sparse directory entry 'ce', compare ce->name to
1245
+ * info->name + '/' + p->path + '/' if info->name is non-empty.
1246
+ * Compare ce->name to p->path + '/' otherwise. Note that
1247
+ * ce->name must end in a trailing '/' because it is a sparse
1248
+ * directory entry.
1249
+ */
1250
+static int sparse_dir_matches_path(const struct cache_entry *ce,
1251
+ struct traverse_info *info,
1252
+ const struct name_entry *p)
1253
+{
1254
+ assert(S_ISSPARSEDIR(ce->ce_mode));
1255
+ assert(ce->name[ce->ce_namelen - 1] == '/');
1256
+
1257
+ if (info->namelen)
1258
+ return ce->ce_namelen == info->namelen + p->pathlen + 2 &&
1259
+ ce->name[info->namelen] == '/' &&
1260
+ !strncmp(ce->name, info->name, info->namelen) &&
1261
+ !strncmp(ce->name + info->namelen + 1, p->path, p->pathlen);
1262
+ return ce->ce_namelen == p->pathlen + 1 &&
1263
+ !strncmp(ce->name, p->path, p->pathlen);
1264
+}
1265
+
1266
static struct cache_entry *find_cache_entry(struct traverse_info *info,
1267
const struct name_entry *p)
1268
{
1269
+ struct cache_entry *ce;
1270
int pos = find_cache_pos(info, p->path, p->pathlen);
1271
struct unpack_trees_options *o = info->data;
1272
1273
if (0 <= pos)
1274
return o->src_index->cache[pos];
1233
- else
1275
+
1276
+ /*
1277
+ * Check for a sparse-directory entry named "path/".
1278
+ * Due to the input p->path not having a trailing
1279
+ * slash, the negative 'pos' value overshoots the
1280
+ * expected position, hence "-2" instead of "-1".
1281
+ */
1282
+ pos = -pos - 2;
1283
+
1284
+ if (pos < 0 || pos >= o->src_index->cache_nr)
1285
return NULL;
1286
+
1287
+ /*
1288
+ * Due to lexicographic sorting and sparse directory
1289
+ * entries ending with a trailing slash, our path as a
1290
+ * sparse directory (e.g "subdir/") and our path as a
1291
+ * file (e.g. "subdir") might be separated by other
1292
+ * paths (e.g. "subdir-").
1293
+ */
1294
+ while (pos >= 0) {
1295
+ ce = o->src_index->cache[pos];
1296
+
1297
+ if (strncmp(ce->name, p->path, p->pathlen))
1298
+ return NULL;
1299
+
1300
+ if (S_ISSPARSEDIR(ce->ce_mode) &&
1301
+ sparse_dir_matches_path(ce, info, p))
1302
+ return ce;
1303
+
1304
+ pos--;
1305
+ }
1306
+
1307
+ return NULL;
1308
}
1309
1310
static void debug_path(struct traverse_info *info)
1339
debug_name_entry(i, names + i);
1340
}
1341
1342
+/*
1343
+ * Returns true if and only if the given cache_entry is a
1344
+ * sparse-directory entry that matches the given name_entry
1345
+ * from the tree walk at the given traverse_info.
1346
+ */
1347
+static int is_sparse_directory_entry(struct cache_entry *ce,
1348
+ struct name_entry *name,
1349
+ struct traverse_info *info)
1350
+{
1351
+ if (!ce || !name || !S_ISSPARSEDIR(ce->ce_mode))
1352
+ return 0;
1353
+
1354
+ return sparse_dir_matches_path(ce, info, name);
1355
+}
1356
+
1357
/*
1358
* Note that traverse_by_cache_tree() duplicates some logic in this function
1359
* without actually calling it. If you change the logic here you may need to
1440
}
1441
}
1442
1355
- if (traverse_trees_recursive(n, dirmask, mask & ~dirmask,
1356
- names, info) < 0)
1443
+ if (!is_sparse_directory_entry(src[0], names, info) &&
1444
+ traverse_trees_recursive(n, dirmask, mask & ~dirmask,
1445
+ names, info) < 0) {
1446
return -1;
1447
+ }
1448
+
1449
return mask;
1450
}
1451