1069
return ce;
1070
}
1071
1072
+/*
1073
+ * Determine whether the path specified by 'p' should be unpacked as a new
1074
+ * sparse directory in a sparse index. A new sparse directory 'A/':
1075
+ * - must be outside the sparse cone.
1076
+ * - must not already be in the index (i.e., no index entry with name 'A/'
1077
+ * exists).
1078
+ * - must not have any child entries in the index (i.e., no index entry
1079
+ * 'A/<something>' exists).
1080
+ * If 'p' meets the above requirements, return 1; otherwise, return 0.
1081
+ */
1082
+static int entry_is_new_sparse_dir(const struct traverse_info *info,
1083
+ const struct name_entry *p)
1084
+{
1085
+ int res, pos;
1086
+ struct strbuf dirpath = STRBUF_INIT;
1087
+ struct unpack_trees_options *o = info->data;
1088
+
1089
+ if (!S_ISDIR(p->mode))
1090
+ return 0;
1091
+
1092
+ /*
1093
+ * If the path is inside the sparse cone, it can't be a sparse directory.
1094
+ */
1095
+ strbuf_add(&dirpath, info->traverse_path, info->pathlen);
1096
+ strbuf_add(&dirpath, p->path, p->pathlen);
1097
+ strbuf_addch(&dirpath, '/');
1098
+ if (path_in_cone_mode_sparse_checkout(dirpath.buf, o->src_index)) {
1099
+ res = 0;
1100
+ goto cleanup;
1101
+ }
1102
+
1103
+ pos = index_name_pos_sparse(o->src_index, dirpath.buf, dirpath.len);
1104
+ if (pos >= 0) {
1105
+ /* Path is already in the index, not a new sparse dir */
1106
+ res = 0;
1107
+ goto cleanup;
1108
+ }
1109
+
1110
+ /* Where would this sparse dir be inserted into the index? */
1111
+ pos = -pos - 1;
1112
+ if (pos >= o->src_index->cache_nr) {
1113
+ /*
1114
+ * Sparse dir would be inserted at the end of the index, so we
1115
+ * know it has no child entries.
1116
+ */
1117
+ res = 1;
1118
+ goto cleanup;
1119
+ }
1120
+
1121
+ /*
1122
+ * If the dir has child entries in the index, the first would be at the
1123
+ * position the sparse directory would be inserted. If the entry at this
1124
+ * position is inside the dir, not a new sparse dir.
1125
+ */
1126
+ res = strncmp(o->src_index->cache[pos]->name, dirpath.buf, dirpath.len);
1127
+
1128
+cleanup:
1129
+ strbuf_release(&dirpath);
1130
+ return res;
1131
+}
1132
+
1133
/*
1134
* Note that traverse_by_cache_tree() duplicates some logic in this function
1135
* without actually calling it. If you change the logic here you may need to
1139
unsigned long dirmask,
1140
struct cache_entry **src,
1141
const struct name_entry *names,
1081
- const struct traverse_info *info)
1142
+ const struct traverse_info *info,
1143
+ int *is_new_sparse_dir)
1144
{
1145
int i;
1146
struct unpack_trees_options *o = info->data;
1147
unsigned long conflicts = info->df_conflicts | dirmask;
1148
+ const struct name_entry *p = names;
1149
1087
- if (mask == dirmask && !src[0])
1088
- return 0;
1150
+ *is_new_sparse_dir = 0;
1151
+ if (mask == dirmask && !src[0]) {
1152
+ /*
1153
+ * If we're not in a sparse index, we can't unpack a directory
1154
+ * without recursing into it, so we return.
1155
+ */
1156
+ if (!o->src_index->sparse_index)
1157
+ return 0;
1158
+
1159
+ /* Find first entry with a real name (we could use "mask" too) */
1160
+ while (!p->mode)
1161
+ p++;
1162
+
1163
+ /*
1164
+ * If the directory is completely missing from the index but
1165
+ * would otherwise be a sparse directory, we should unpack it.
1166
+ * If not, we'll return and continue recursively traversing the
1167
+ * tree.
1168
+ */
1169
+ *is_new_sparse_dir = entry_is_new_sparse_dir(info, p);
1170
+ if (!*is_new_sparse_dir)
1171
+ return 0;
1172
+ }
1173
1174
/*
1091
- * When we have a sparse directory entry for src[0],
1092
- * then this isn't necessarily a directory-file conflict.
1175
+ * When we are unpacking a sparse directory, then this isn't necessarily
1176
+ * a directory-file conflict.
1177
*/
1094
- if (mask == dirmask && src[0] &&
1095
- S_ISSPARSEDIR(src[0]->ce_mode))
1178
+ if (mask == dirmask &&
1179
+ (*is_new_sparse_dir || (src[0] && S_ISSPARSEDIR(src[0]->ce_mode))))
1180
conflicts = 0;
1181
1182
/*
1436
{
1437
struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
1438
struct unpack_trees_options *o = info->data;
1355
- int ret;
1439
+ int ret, is_new_sparse_dir;
1440
1441
assert(o->merge);
1442
1460
* "index" tree (i.e., names[0]) and adjust 'names', 'n', 'mask', and
1461
* 'dirmask' accordingly.
1462
*/
1379
- ret = unpack_single_entry(n - 1, mask >> 1, dirmask >> 1, src, names + 1, info);
1463
+ ret = unpack_single_entry(n - 1, mask >> 1, dirmask >> 1, src, names + 1, info, &is_new_sparse_dir);
1464
1465
if (src[0])
1466
discard_cache_entry(src[0]);
1478
struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
1479
struct unpack_trees_options *o = info->data;
1480
const struct name_entry *p = names;
1481
+ int is_new_sparse_dir;
1482
1483
/* Find first entry with a real name (we could use "mask" too) */
1484
while (!p->mode)
1525
}
1526
}
1527
1443
- if (unpack_single_entry(n, mask, dirmask, src, names, info) < 0)
1528
+ if (unpack_single_entry(n, mask, dirmask, src, names, info, &is_new_sparse_dir))
1529
return -1;
1530
1531
if (o->merge && src[0]) {
1563
}
1564
1565
if (!is_sparse_directory_entry(src[0], names, info) &&
1566
+ !is_new_sparse_dir &&
1567
traverse_trees_recursive(n, dirmask, mask & ~dirmask,
1568
names, info) < 0) {
1569
return -1;