Coverage Report

Created: 2026-10-17 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/sparse-index.c
Line
Count
Source
1
#define USE_THE_REPOSITORY_VARIABLE
2
#define DISABLE_SIGN_COMPARE_WARNINGS
3
4
#include "git-compat-util.h"
5
#include "environment.h"
6
#include "ewah/ewok.h"
7
#include "gettext.h"
8
#include "name-hash.h"
9
#include "read-cache-ll.h"
10
#include "repository.h"
11
#include "sparse-index.h"
12
#include "tree.h"
13
#include "pathspec.h"
14
#include "trace2.h"
15
#include "cache-tree.h"
16
#include "config.h"
17
#include "dir.h"
18
#include "fsmonitor-ll.h"
19
#include "advice.h"
20
21
/**
22
 * This global is used by expand_index() to determine if we should give the
23
 * advice for advice.sparseIndexExpanded when expanding a sparse index to a full
24
 * one. However, this is sometimes done on purpose, such as in the sparse-checkout
25
 * builtin, even when index.sparse=false. This may be disabled in
26
 * convert_to_sparse() or by commands that know they will lead to a full
27
 * expansion, but this message is not actionable.
28
 */
29
int give_advice_on_expansion = 1;
30
#define ADVICE_MSG \
31
0
  "The sparse index is expanding to a full index, a slow operation.\n"   \
32
0
  "Your working directory likely has contents that are outside of\n"     \
33
0
  "your sparse-checkout patterns. Use 'git sparse-checkout list' to\n"   \
34
0
  "see your sparse-checkout definition and compare it to your working\n" \
35
0
  "directory contents. Cleaning up any merge conflicts or staged\n"      \
36
0
  "changes before running 'git sparse-checkout clean' or 'git\n"         \
37
0
  "sparse-checkout reapply' may assist in this cleanup."
38
39
struct modify_index_context {
40
  struct index_state *write;
41
  struct pattern_list *pl;
42
};
43
44
static struct cache_entry *construct_sparse_dir_entry(
45
        struct index_state *istate,
46
        const char *sparse_dir,
47
        struct cache_tree *tree)
48
0
{
49
0
  struct cache_entry *de;
50
51
0
  de = make_cache_entry(istate, S_IFDIR, &tree->oid, sparse_dir, 0, 0);
52
53
0
  de->ce_flags |= CE_SKIP_WORKTREE;
54
0
  return de;
55
0
}
56
57
/*
58
 * Returns the number of entries "inserted" into the index.
59
 */
60
static int convert_to_sparse_rec(struct index_state *istate,
61
         int num_converted,
62
         int start, int end,
63
         const char *ct_path, size_t ct_pathlen,
64
         struct cache_tree *ct)
65
0
{
66
0
  int i, can_convert = 1;
67
0
  int start_converted = num_converted;
68
0
  struct strbuf child_path = STRBUF_INIT;
69
70
  /*
71
   * Is the current path outside of the sparse cone?
72
   * Then check if the region can be replaced by a sparse
73
   * directory entry (everything is sparse and merged).
74
   */
75
0
  if (path_in_sparse_checkout(ct_path, istate))
76
0
    can_convert = 0;
77
78
0
  for (i = start; can_convert && i < end; i++) {
79
0
    struct cache_entry *ce = istate->cache[i];
80
81
0
    if (ce_stage(ce) ||
82
0
        S_ISGITLINK(ce->ce_mode) ||
83
0
        !(ce->ce_flags & CE_SKIP_WORKTREE))
84
0
      can_convert = 0;
85
0
  }
86
87
0
  if (can_convert) {
88
0
    struct cache_entry *se;
89
0
    se = construct_sparse_dir_entry(istate, ct_path, ct);
90
91
0
    istate->cache[num_converted++] = se;
92
0
    return 1;
93
0
  }
94
95
0
  for (i = start; i < end; ) {
96
0
    int count, span, pos = -1;
97
0
    const char *base, *slash;
98
0
    struct cache_entry *ce = istate->cache[i];
99
100
    /*
101
     * Detect if this is a normal entry outside of any subtree
102
     * entry.
103
     */
104
0
    base = ce->name + ct_pathlen;
105
0
    slash = strchr(base, '/');
106
107
0
    if (slash)
108
0
      pos = cache_tree_subtree_pos(ct, base, slash - base);
109
110
0
    if (pos < 0) {
111
0
      istate->cache[num_converted++] = ce;
112
0
      i++;
113
0
      continue;
114
0
    }
115
116
0
    span = ct->down[pos]->cache_tree->entry_count;
117
0
    if (span < 0) {
118
      /* cache-tree entry is invalidated, cannot collapse. */
119
0
      istate->cache[num_converted++] = ce;
120
0
      i++;
121
0
      continue;
122
0
    }
123
124
0
    strbuf_setlen(&child_path, 0);
125
0
    strbuf_add(&child_path, ce->name, slash - ce->name + 1);
126
127
0
    count = convert_to_sparse_rec(istate,
128
0
                num_converted, i, i + span,
129
0
                child_path.buf, child_path.len,
130
0
                ct->down[pos]->cache_tree);
131
0
    num_converted += count;
132
0
    i += span;
133
0
  }
134
135
0
  strbuf_release(&child_path);
136
0
  return num_converted - start_converted;
137
0
}
138
139
int set_sparse_index_config(struct repository *repo, int enable)
140
0
{
141
0
  int res = repo_config_set_worktree_gently(repo,
142
0
              "index.sparse",
143
0
              enable ? "true" : "false");
144
0
  prepare_repo_settings(repo);
145
0
  repo->settings.sparse_index = enable;
146
0
  return res;
147
0
}
148
149
static int index_has_unmerged_entries(struct index_state *istate)
150
0
{
151
0
  int i;
152
0
  for (i = 0; i < istate->cache_nr; i++) {
153
0
    if (ce_stage(istate->cache[i]))
154
0
      return 1;
155
0
  }
156
157
0
  return 0;
158
0
}
159
160
int is_sparse_index_allowed(struct index_state *istate, int flags)
161
0
{
162
0
  struct repo_config_values *cfg = repo_config_values(the_repository);
163
164
0
  if (!cfg->apply_sparse_checkout || !cfg->core_sparse_checkout_cone)
165
0
    return 0;
166
167
0
  if (!(flags & SPARSE_INDEX_MEMORY_ONLY)) {
168
0
    int test_env;
169
170
    /*
171
     * The sparse index is not (yet) integrated with a split index.
172
     */
173
0
    if (istate->split_index || git_env_bool("GIT_TEST_SPLIT_INDEX", 0))
174
0
      return 0;
175
    /*
176
     * The GIT_TEST_SPARSE_INDEX environment variable triggers the
177
     * index.sparse config variable to be on.
178
     */
179
0
    test_env = git_env_bool("GIT_TEST_SPARSE_INDEX", -1);
180
0
    if (test_env >= 0)
181
0
      set_sparse_index_config(istate->repo, test_env);
182
183
    /*
184
     * Only convert to sparse if index.sparse is set.
185
     */
186
0
    prepare_repo_settings(istate->repo);
187
0
    if (!istate->repo->settings.sparse_index)
188
0
      return 0;
189
0
  }
190
191
0
  if (init_sparse_checkout_patterns(istate))
192
0
    return 0;
193
194
  /*
195
   * We need cone-mode patterns to use sparse-index. If a user edits
196
   * their sparse-checkout file manually, then we can detect during
197
   * parsing that they are not actually using cone-mode patterns and
198
   * hence we need to abort this conversion _without error_. Warnings
199
   * already exist in the pattern parsing to inform the user of their
200
   * bad patterns.
201
   */
202
0
  if (!istate->sparse_checkout_patterns->use_cone_patterns)
203
0
    return 0;
204
205
0
  return 1;
206
0
}
207
208
int convert_to_sparse(struct index_state *istate, int flags)
209
0
{
210
  /*
211
   * If the index is already sparse, empty, or otherwise
212
   * cannot be converted to sparse, do not convert.
213
   */
214
0
  if (istate->sparse_index == INDEX_COLLAPSED || !istate->cache_nr ||
215
0
      !is_sparse_index_allowed(istate, flags))
216
0
    return 0;
217
218
  /*
219
   * If we are purposefully collapsing a full index, then don't give
220
   * advice when it is expanded later.
221
   */
222
0
  give_advice_on_expansion = 0;
223
224
  /*
225
   * NEEDSWORK: If we have unmerged entries, then stay full.
226
   * Unmerged entries prevent the cache-tree extension from working.
227
   */
228
0
  if (index_has_unmerged_entries(istate))
229
0
    return 0;
230
231
0
  if (!cache_tree_fully_valid(istate)) {
232
    /* Clear and recompute the cache-tree */
233
0
    cache_tree_free(&istate->cache_tree);
234
235
    /*
236
     * Silently return if there is a problem with the cache tree update,
237
     * which might just be due to a conflict state in some entry.
238
     *
239
     * This might create new tree objects, so be sure to use
240
     * WRITE_TREE_MISSING_OK.
241
     */
242
0
    if (cache_tree_update(istate, WRITE_TREE_MISSING_OK))
243
0
      return 0;
244
0
  }
245
246
0
  remove_fsmonitor(istate);
247
248
0
  trace2_region_enter("index", "convert_to_sparse", istate->repo);
249
0
  istate->cache_nr = convert_to_sparse_rec(istate,
250
0
             0, 0, istate->cache_nr,
251
0
             "", 0, istate->cache_tree);
252
253
  /* Clear and recompute the cache-tree */
254
0
  cache_tree_free(&istate->cache_tree);
255
0
  cache_tree_update(istate, 0);
256
257
0
  istate->fsmonitor_has_run_once = 0;
258
0
  ewah_free(istate->fsmonitor_dirty);
259
0
  istate->fsmonitor_dirty = NULL;
260
0
  FREE_AND_NULL(istate->fsmonitor_last_update);
261
262
0
  istate->sparse_index = INDEX_COLLAPSED;
263
0
  trace2_region_leave("index", "convert_to_sparse", istate->repo);
264
0
  return 0;
265
0
}
266
267
static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce)
268
0
{
269
0
  ALLOC_GROW(istate->cache, nr + 1, istate->cache_alloc);
270
271
0
  istate->cache[nr] = ce;
272
0
  add_name_hash(istate, ce);
273
0
}
274
275
static int add_path_to_index(const struct object_id *oid,
276
           struct strbuf *base, const char *path,
277
           unsigned int mode, void *context)
278
0
{
279
0
  struct modify_index_context *ctx = (struct modify_index_context *)context;
280
0
  struct cache_entry *ce;
281
0
  size_t len = base->len;
282
283
0
  if (S_ISDIR(mode)) {
284
0
    int dtype;
285
0
    size_t baselen = base->len;
286
0
    if (!ctx->pl)
287
0
      return READ_TREE_RECURSIVE;
288
289
    /*
290
     * Have we expanded to a point outside of the sparse-checkout?
291
     *
292
     * Artificially pad the path name with a slash "/" to
293
     * indicate it as a directory, and add an arbitrary file
294
     * name ("-") so we can consider base->buf as a file name
295
     * to match against the cone-mode patterns.
296
     *
297
     * If we compared just "path", then we would expand more
298
     * than we should. Since every file at root is always
299
     * included, we would expand every directory at root at
300
     * least one level deep instead of using sparse directory
301
     * entries.
302
     */
303
0
    strbuf_addstr(base, path);
304
0
    strbuf_add(base, "/-", 2);
305
306
0
    if (path_matches_pattern_list(base->buf, base->len,
307
0
                NULL, &dtype,
308
0
                ctx->pl, ctx->write)) {
309
0
      strbuf_setlen(base, baselen);
310
0
      return READ_TREE_RECURSIVE;
311
0
    }
312
313
    /*
314
     * The path "{base}{path}/" is a sparse directory. Create the correct
315
     * name for inserting the entry into the index.
316
     */
317
0
    strbuf_setlen(base, base->len - 1);
318
0
  } else {
319
0
    strbuf_addstr(base, path);
320
0
  }
321
322
0
  ce = make_cache_entry(ctx->write, mode, oid, base->buf, 0, 0);
323
0
  ce->ce_flags |= CE_SKIP_WORKTREE | CE_EXTENDED;
324
0
  set_index_entry(ctx->write, ctx->write->cache_nr++, ce);
325
326
0
  strbuf_setlen(base, len);
327
0
  return 0;
328
0
}
329
330
void expand_index(struct index_state *istate, struct pattern_list *pl)
331
0
{
332
0
  int i;
333
0
  struct index_state *full;
334
0
  struct strbuf base = STRBUF_INIT;
335
0
  const char *tr_region;
336
0
  struct modify_index_context ctx;
337
338
  /*
339
   * If the index is already full, then keep it full. We will convert
340
   * it to a sparse index on write, if possible.
341
   */
342
0
  if (istate->sparse_index == INDEX_EXPANDED)
343
0
    return;
344
345
  /*
346
   * If our index is sparse, but our new pattern set does not use
347
   * cone mode patterns, then we need to expand the index before we
348
   * continue. A NULL pattern set indicates a full expansion to a
349
   * full index.
350
   */
351
0
  if (pl && !pl->use_cone_patterns) {
352
0
    pl = NULL;
353
0
  } else {
354
    /*
355
     * We might contract file entries into sparse-directory
356
     * entries, and for that we will need the cache tree to
357
     * be recomputed.
358
     */
359
0
    cache_tree_free(&istate->cache_tree);
360
361
    /*
362
     * If there is a problem creating the cache tree, then we
363
     * need to expand to a full index since we cannot satisfy
364
     * the current request as a sparse index.
365
     */
366
0
    if (cache_tree_update(istate, 0))
367
0
      pl = NULL;
368
0
  }
369
370
0
  if (!pl && give_advice_on_expansion) {
371
0
    give_advice_on_expansion = 0;
372
0
    advise_if_enabled(ADVICE_SPARSE_INDEX_EXPANDED,
373
0
          _(ADVICE_MSG));
374
0
  }
375
376
  /*
377
   * A NULL pattern set indicates we are expanding a full index, so
378
   * we use a special region name that indicates the full expansion.
379
   * This is used by test cases, but also helps to differentiate the
380
   * two cases.
381
   */
382
0
  tr_region = pl ? "expand_index" : "ensure_full_index";
383
0
  trace2_region_enter("index", tr_region, istate->repo);
384
385
  /* initialize basics of new index */
386
0
  full = xcalloc(1, sizeof(struct index_state));
387
0
  memcpy(full, istate, sizeof(struct index_state));
388
389
  /*
390
   * This slightly-misnamed 'full' index might still be sparse if we
391
   * are only modifying the list of sparse directories. This hinges
392
   * on whether we have a non-NULL pattern list.
393
   */
394
0
  full->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;
395
396
  /* then change the necessary things */
397
0
  full->cache_alloc = (3 * istate->cache_alloc) / 2;
398
0
  full->cache_nr = 0;
399
0
  ALLOC_ARRAY(full->cache, full->cache_alloc);
400
401
0
  ctx.write = full;
402
0
  ctx.pl = pl;
403
404
0
  for (i = 0; i < istate->cache_nr; i++) {
405
0
    struct cache_entry *ce = istate->cache[i];
406
0
    struct tree *tree;
407
0
    struct pathspec ps;
408
0
    int dtype;
409
410
0
    if (!S_ISSPARSEDIR(ce->ce_mode)) {
411
0
      set_index_entry(full, full->cache_nr++, ce);
412
0
      continue;
413
0
    }
414
415
    /* We now have a sparse directory entry. Should we expand? */
416
0
    if (pl &&
417
0
        path_matches_pattern_list(ce->name, ce->ce_namelen,
418
0
                NULL, &dtype,
419
0
                pl, istate) == NOT_MATCHED) {
420
0
      set_index_entry(full, full->cache_nr++, ce);
421
0
      continue;
422
0
    }
423
424
0
    if (!(ce->ce_flags & CE_SKIP_WORKTREE))
425
0
      warning(_("index entry is a directory, but not sparse (%08x)"),
426
0
        ce->ce_flags);
427
428
    /* recursively walk into cd->name */
429
0
    tree = lookup_tree(istate->repo, &ce->oid);
430
431
0
    memset(&ps, 0, sizeof(ps));
432
0
    ps.recursive = 1;
433
0
    ps.has_wildcard = 1;
434
0
    ps.max_depth = -1;
435
436
0
    strbuf_setlen(&base, 0);
437
0
    strbuf_add(&base, ce->name, strlen(ce->name));
438
439
0
    read_tree_at(istate->repo, tree, &base, 0, &ps,
440
0
           add_path_to_index, &ctx);
441
442
    /* free directory entries. full entries are re-used */
443
0
    discard_cache_entry(ce);
444
0
  }
445
446
  /* Copy back into original index. */
447
0
  memcpy(&istate->name_hash, &full->name_hash, sizeof(full->name_hash));
448
0
  memcpy(&istate->dir_hash, &full->dir_hash, sizeof(full->dir_hash));
449
0
  istate->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED;
450
0
  free(istate->cache);
451
0
  istate->cache = full->cache;
452
0
  istate->cache_nr = full->cache_nr;
453
0
  istate->cache_alloc = full->cache_alloc;
454
0
  istate->fsmonitor_has_run_once = 0;
455
0
  ewah_free(istate->fsmonitor_dirty);
456
0
  istate->fsmonitor_dirty = NULL;
457
0
  FREE_AND_NULL(istate->fsmonitor_last_update);
458
459
0
  strbuf_release(&base);
460
0
  free(full);
461
462
  /* Clear and recompute the cache-tree */
463
0
  cache_tree_free(&istate->cache_tree);
464
0
  cache_tree_update(istate, 0);
465
466
0
  trace2_region_leave("index", tr_region, istate->repo);
467
0
}
468
469
void ensure_full_index(struct index_state *istate)
470
0
{
471
0
  if (!istate)
472
0
    BUG("ensure_full_index() must get an index!");
473
0
  expand_index(istate, NULL);
474
0
}
475
476
void ensure_correct_sparsity(struct index_state *istate)
477
0
{
478
  /*
479
   * If the index can be sparse, make it sparse. Otherwise,
480
   * ensure the index is full.
481
   */
482
0
  if (is_sparse_index_allowed(istate, 0))
483
0
    convert_to_sparse(istate, 0);
484
0
  else
485
0
    ensure_full_index(istate);
486
0
}
487
488
struct path_found_data {
489
  /**
490
   * The path stored in 'dir', if non-empty, corresponds to the most-
491
   * recent path that we checked where:
492
   *
493
   *   1. The path should be a directory, according to the index.
494
   *   2. The path does not exist.
495
   *   3. The parent path _does_ exist. (This may be the root of the
496
   *      working directory.)
497
   */
498
  struct strbuf dir;
499
  size_t lstat_count;
500
};
501
502
0
#define PATH_FOUND_DATA_INIT { \
503
0
  .dir = STRBUF_INIT \
504
0
}
505
506
static void clear_path_found_data(struct path_found_data *data)
507
0
{
508
0
  strbuf_release(&data->dir);
509
0
}
510
511
/**
512
 * Return the length of the longest common substring that ends in a
513
 * slash ('/') to indicate the longest common parent directory. Returns
514
 * zero if no common directory exists.
515
 */
516
static size_t max_common_dir_prefix(const char *path1, const char *path2)
517
0
{
518
0
  size_t common_prefix = 0;
519
0
  for (size_t i = 0; path1[i] && path2[i]; i++) {
520
0
    if (path1[i] != path2[i])
521
0
      break;
522
523
    /*
524
     * If they agree at a directory separator, then add one
525
     * to make sure it is included in the common prefix string.
526
     */
527
0
    if (path1[i] == '/')
528
0
      common_prefix = i + 1;
529
0
  }
530
531
0
  return common_prefix;
532
0
}
533
534
static int path_found(const char *path, struct path_found_data *data)
535
0
{
536
0
  struct stat st;
537
0
  size_t common_prefix;
538
539
  /*
540
   * If data->dir is non-empty, then it contains a path that doesn't
541
   * exist, including an ending slash ('/'). If it is a prefix of 'path',
542
   * then we can return 0.
543
   */
544
0
  if (data->dir.len && !memcmp(path, data->dir.buf, data->dir.len))
545
0
    return 0;
546
547
  /*
548
   * Otherwise, we must check if the current path exists. If it does, then
549
   * return 1. The cached directory will be skipped until we come across
550
   * a missing path again.
551
   */
552
0
  data->lstat_count++;
553
0
  if (!lstat(path, &st))
554
0
    return 1;
555
556
  /*
557
   * At this point, we know that 'path' doesn't exist, and we know that
558
   * the parent directory of 'data->dir' does exist. Let's set 'data->dir'
559
   * to be the top-most non-existing directory of 'path'. If the first
560
   * parent of 'path' exists, then we will act as though 'path'
561
   * corresponds to a directory (by adding a slash).
562
   */
563
0
  common_prefix = max_common_dir_prefix(path, data->dir.buf);
564
565
  /*
566
   * At this point, 'path' and 'data->dir' have a common existing parent
567
   * directory given by path[0..common_prefix] (which could have length 0).
568
   * We "grow" the data->dir buffer by checking for existing directories
569
   * along 'path'.
570
   */
571
572
0
  strbuf_setlen(&data->dir, common_prefix);
573
0
  while (1) {
574
    /* Find the next directory in 'path'. */
575
0
    const char *rest = path + data->dir.len;
576
0
    const char *next_slash = strchr(rest, '/');
577
578
    /*
579
     * If there are no more slashes, then 'path' doesn't contain a
580
     * non-existent _parent_ directory. Set 'data->dir' to be equal
581
     * to 'path' plus an additional slash, so it can be used for
582
     * caching in the future. The filename of 'path' is considered
583
     * a non-existent directory.
584
     *
585
     * Note: if "{path}/" exists as a directory, then it will never
586
     * appear as a prefix of other callers to this method, assuming
587
     * the context from the clear_skip_worktree... methods. If this
588
     * method is reused, then this must be reconsidered.
589
     */
590
0
    if (!next_slash) {
591
0
      strbuf_addstr(&data->dir, rest);
592
0
      strbuf_addch(&data->dir, '/');
593
0
      break;
594
0
    }
595
596
    /*
597
     * Now that we have a slash, let's grow 'data->dir' to include
598
     * this slash, then test if we should stop.
599
     */
600
0
    strbuf_add(&data->dir, rest, next_slash - rest + 1);
601
602
    /* If the parent dir doesn't exist, then stop here. */
603
0
    data->lstat_count++;
604
0
    if (lstat(data->dir.buf, &st))
605
0
      return 0;
606
0
  }
607
608
  /*
609
   * At this point, 'data->dir' is equal to 'path' plus a slash character,
610
   * and the parent directory of 'path' definitely exists. Moreover, we
611
   * know that 'path' doesn't exist, or we would have returned 1 earlier.
612
   */
613
0
  return 0;
614
0
}
615
616
static int clear_skip_worktree_from_present_files_sparse(struct index_state *istate)
617
0
{
618
0
  struct path_found_data data = PATH_FOUND_DATA_INIT;
619
620
0
  int path_count = 0;
621
0
  int to_restart = 0;
622
623
0
  trace2_region_enter("index", "clear_skip_worktree_from_present_files_sparse",
624
0
          istate->repo);
625
0
  for (int i = 0; i < istate->cache_nr; i++) {
626
0
    struct cache_entry *ce = istate->cache[i];
627
628
0
    if (ce_skip_worktree(ce)) {
629
0
      path_count++;
630
0
      if (path_found(ce->name, &data)) {
631
0
        if (S_ISSPARSEDIR(ce->ce_mode)) {
632
0
          to_restart = 1;
633
0
          break;
634
0
        }
635
0
        ce->ce_flags &= ~CE_SKIP_WORKTREE;
636
0
      }
637
0
    }
638
0
  }
639
640
0
  trace2_data_intmax("index", istate->repo,
641
0
         "sparse_path_count", path_count);
642
0
  trace2_data_intmax("index", istate->repo,
643
0
         "sparse_lstat_count", data.lstat_count);
644
0
  trace2_region_leave("index", "clear_skip_worktree_from_present_files_sparse",
645
0
          istate->repo);
646
0
  clear_path_found_data(&data);
647
0
  return to_restart;
648
0
}
649
650
static void clear_skip_worktree_from_present_files_full(struct index_state *istate)
651
0
{
652
0
  struct path_found_data data = PATH_FOUND_DATA_INIT;
653
654
0
  int path_count = 0;
655
656
0
  trace2_region_enter("index", "clear_skip_worktree_from_present_files_full",
657
0
          istate->repo);
658
0
  for (int i = 0; i < istate->cache_nr; i++) {
659
0
    struct cache_entry *ce = istate->cache[i];
660
661
0
    if (S_ISSPARSEDIR(ce->ce_mode))
662
0
      BUG("ensure-full-index did not fully flatten?");
663
664
0
    if (ce_skip_worktree(ce)) {
665
0
      path_count++;
666
0
      if (path_found(ce->name, &data))
667
0
        ce->ce_flags &= ~CE_SKIP_WORKTREE;
668
0
    }
669
0
  }
670
671
0
  trace2_data_intmax("index", istate->repo,
672
0
         "full_path_count", path_count);
673
0
  trace2_data_intmax("index", istate->repo,
674
0
         "full_lstat_count", data.lstat_count);
675
0
  trace2_region_leave("index", "clear_skip_worktree_from_present_files_full",
676
0
          istate->repo);
677
0
  clear_path_found_data(&data);
678
0
}
679
680
void clear_skip_worktree_from_present_files(struct index_state *istate)
681
0
{
682
0
  struct repo_config_values *cfg = repo_config_values(the_repository);
683
684
0
  if (!cfg->apply_sparse_checkout ||
685
0
      cfg->sparse_expect_files_outside_of_patterns)
686
0
    return;
687
688
0
  if (clear_skip_worktree_from_present_files_sparse(istate)) {
689
0
    ensure_full_index(istate);
690
0
    clear_skip_worktree_from_present_files_full(istate);
691
0
  }
692
0
}
693
694
/*
695
 * This static global helps avoid infinite recursion between
696
 * expand_to_path() and index_file_exists().
697
 */
698
static int in_expand_to_path = 0;
699
700
void expand_to_path(struct index_state *istate,
701
        const char *path, size_t pathlen, int icase)
702
0
{
703
0
  struct strbuf path_mutable = STRBUF_INIT;
704
0
  size_t substr_len;
705
706
  /* prevent extra recursion */
707
0
  if (in_expand_to_path)
708
0
    return;
709
710
0
  if (!istate->sparse_index)
711
0
    return;
712
713
0
  in_expand_to_path = 1;
714
715
  /*
716
   * We only need to actually expand a region if the
717
   * following are both true:
718
   *
719
   * 1. 'path' is not already in the index.
720
   * 2. Some parent directory of 'path' is a sparse directory.
721
   */
722
723
0
  if (index_file_exists(istate, path, pathlen, icase))
724
0
    goto cleanup;
725
726
0
  strbuf_add(&path_mutable, path, pathlen);
727
0
  strbuf_addch(&path_mutable, '/');
728
729
  /* Check the name hash for all parent directories */
730
0
  substr_len = 0;
731
0
  while (substr_len < pathlen) {
732
0
    char temp;
733
0
    char *replace = strchr(path_mutable.buf + substr_len, '/');
734
735
0
    if (!replace)
736
0
      break;
737
738
    /* replace the character _after_ the slash */
739
0
    replace++;
740
0
    temp = *replace;
741
0
    *replace = '\0';
742
0
    substr_len = replace - path_mutable.buf;
743
0
    if (index_file_exists(istate, path_mutable.buf,
744
0
              substr_len, icase)) {
745
      /*
746
       * We found a parent directory in the name-hash
747
       * hashtable, because only sparse directory entries
748
       * have a trailing '/' character.  Since "path" wasn't
749
       * in the index, perhaps it exists within this
750
       * sparse-directory.  Expand accordingly.
751
       */
752
0
      ensure_full_index(istate);
753
0
      break;
754
0
    }
755
756
0
    *replace = temp;
757
0
  }
758
759
0
cleanup:
760
0
  strbuf_release(&path_mutable);
761
0
  in_expand_to_path = 0;
762
0
}