9
#include "dir.h"
10
#include "fsmonitor.h"
11
12
+struct modify_index_context {
13
+ struct index_state *write;
14
+ struct pattern_list *pl;
15
+};
16
+
17
static struct cache_entry *construct_sparse_dir_entry(
18
struct index_state *istate,
19
const char *sparse_dir,
236
struct strbuf *base, const char *path,
237
unsigned int mode, void *context)
238
{
234
- struct index_state *istate = (struct index_state *)context;
239
+ struct modify_index_context *ctx = (struct modify_index_context *)context;
240
struct cache_entry *ce;
241
size_t len = base->len;
242
238
- if (S_ISDIR(mode))
239
- return READ_TREE_RECURSIVE;
243
+ if (S_ISDIR(mode)) {
244
+ int dtype;
245
+ size_t baselen = base->len;
246
+ if (!ctx->pl)
247
+ return READ_TREE_RECURSIVE;
248
241
- strbuf_addstr(base, path);
249
+ /*
250
+ * Have we expanded to a point outside of the sparse-checkout?
251
+ *
252
+ * Artificially pad the path name with a slash "/" to
253
+ * indicate it as a directory, and add an arbitrary file
254
+ * name ("-") so we can consider base->buf as a file name
255
+ * to match against the cone-mode patterns.
256
+ *
257
+ * If we compared just "path", then we would expand more
258
+ * than we should. Since every file at root is always
259
+ * included, we would expand every directory at root at
260
+ * least one level deep instead of using sparse directory
261
+ * entries.
262
+ */
263
+ strbuf_addstr(base, path);
264
+ strbuf_add(base, "/-", 2);
265
+
266
+ if (path_matches_pattern_list(base->buf, base->len,
267
+ NULL, &dtype,
268
+ ctx->pl, ctx->write)) {
269
+ strbuf_setlen(base, baselen);
270
+ return READ_TREE_RECURSIVE;
271
+ }
272
243
- ce = make_cache_entry(istate, mode, oid, base->buf, 0, 0);
273
+ /*
274
+ * The path "{base}{path}/" is a sparse directory. Create the correct
275
+ * name for inserting the entry into the index.
276
+ */
277
+ strbuf_setlen(base, base->len - 1);
278
+ } else {
279
+ strbuf_addstr(base, path);
280
+ }
281
+
282
+ ce = make_cache_entry(ctx->write, mode, oid, base->buf, 0, 0);
283
ce->ce_flags |= CE_SKIP_WORKTREE | CE_EXTENDED;
245
- set_index_entry(istate, istate->cache_nr++, ce);
284
+ set_index_entry(ctx->write, ctx->write->cache_nr++, ce);
285
286
strbuf_setlen(base, len);
287
return 0;
293
struct index_state *full;
294
struct strbuf base = STRBUF_INIT;
295
const char *tr_region;
296
+ struct modify_index_context ctx;
297
298
/*
299
* If the index is already full, then keep it full. We will convert
333
full->cache_nr = 0;
334
ALLOC_ARRAY(full->cache, full->cache_alloc);
335
336
+ ctx.write = full;
337
+ ctx.pl = pl;
338
+
339
for (i = 0; i < istate->cache_nr; i++) {
340
struct cache_entry *ce = istate->cache[i];
341
struct tree *tree;
361
strbuf_add(&base, ce->name, strlen(ce->name));
362
363
read_tree_at(istate->repo, tree, &base, &ps,
321
- add_path_to_index, full);
364
+ add_path_to_index, &ctx);
365
366
/* free directory entries. full entries are re-used */
367
discard_cache_entry(ce);