untracked-cache: support sparse checkout
Remove a check that would disable the untracked cache for sparse checkouts. Add tests that ensure that the untracked cache works with sparse checkouts -- specifically considering the case that a file foo/bar is checked out, but foo/.gitignore is not. Signed-off-by: David Turner <dturner@twopensource.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
David Turner committed
Jul 31, 2015 at 13:35 UTC
7687252f3f7def11a862a0fd118c531ee630bd05
2 files changed
+122
-14
dir.c
+3
-14
@@ -1078,10 +1078,9 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
1078
(!untracked || !untracked->valid ||
1079
/*
1080
* .. and .gitignore does not exist before
1081
- * (i.e. null exclude_sha1 and skip_worktree is
1082
- * not set). Then we can skip loading .gitignore,
1083
- * which would result in ENOENT anyway.
1084
- * skip_worktree is taken care in read_directory()
1081
+ * (i.e. null exclude_sha1). Then we can skip
1082
+ * loading .gitignore, which would result in
1083
+ * ENOENT anyway.
1084
*/
1085
!is_null_sha1(untracked->exclude_sha1))) {
1086
/*
@@ -1880,7 +1879,6 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
1879
const struct pathspec *pathspec)
1880
{
1881
struct untracked_cache_dir *root;
1883
- int i;
1882
1883
if (!dir->untracked || getenv("GIT_DISABLE_UNTRACKED_CACHE"))
1884
return NULL;
@@ -1932,15 +1930,6 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
1930
if (dir->exclude_list_group[EXC_CMDL].nr)
1931
return NULL;
1932
1935
- /*
1936
- * An optimization in prep_exclude() does not play well with
1937
- * CE_SKIP_WORKTREE. It's a rare case anyway, if a single
1938
- * entry has that bit set, disable the whole untracked cache.
1939
- */
1940
- for (i = 0; i < active_nr; i++)
1941
- if (ce_skip_worktree(active_cache[i]))
1942
- return NULL;
1943
-
1933
if (!ident_in_untracked(dir->untracked)) {
1934
warning(_("Untracked cache is disabled on this system."));
1935
return NULL;
t/t7063-status-untracked-cache.sh
+119
@@ -354,4 +354,123 @@ EOF
354
test_cmp ../expect ../actual
355
'
356
357
+test_expect_success 'set up for sparse checkout testing' '
358
+ echo two >done/.gitignore &&
359
+ echo three >>done/.gitignore &&
360
+ echo two >done/two &&
361
+ git add -f done/two done/.gitignore &&
362
+ git commit -m "first commit"
363
+'
364
+
365
+test_expect_success 'status after commit' '
366
+ : >../trace &&
367
+ GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
368
+ git status --porcelain >../actual &&
369
+ cat >../status.expect <<EOF &&
370
+?? .gitignore
371
+?? dtwo/
372
+EOF
373
+ test_cmp ../status.expect ../actual &&
374
+ cat >../trace.expect <<EOF &&
375
+node creation: 0
376
+gitignore invalidation: 0
377
+directory invalidation: 0
378
+opendir: 1
379
+EOF
380
+ test_cmp ../trace.expect ../trace
381
+'
382
+
383
+test_expect_success 'untracked cache correct after commit' '
384
+ test-dump-untracked-cache >../actual &&
385
+ cat >../expect <<EOF &&
386
+info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
387
+core.excludesfile 0000000000000000000000000000000000000000
388
+exclude_per_dir .gitignore
389
+flags 00000006
390
+/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
391
+.gitignore
392
+dtwo/
393
+/done/ 0000000000000000000000000000000000000000 recurse valid
394
+/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
395
+/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
396
+two
397
+EOF
398
+ test_cmp ../expect ../actual
399
+'
400
+
401
+test_expect_success 'set up sparse checkout' '
402
+ echo "done/[a-z]*" >.git/info/sparse-checkout &&
403
+ test_config core.sparsecheckout true &&
404
+ git checkout master &&
405
+ git update-index --untracked-cache &&
406
+ git status --porcelain >/dev/null && # prime the cache
407
+ test_path_is_missing done/.gitignore &&
408
+ test_path_is_file done/one
409
+'
410
+
411
+test_expect_success 'create files, some of which are gitignored' '
412
+ echo three >done/three && # three is gitignored
413
+ echo four >done/four && # four is gitignored at a higher level
414
+ echo five >done/five # five is not gitignored
415
+'
416
+
417
+test_expect_success 'test sparse status with untracked cache' '
418
+ : >../trace &&
419
+ avoid_racy &&
420
+ GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
421
+ git status --porcelain >../status.actual &&
422
+ cat >../status.expect <<EOF &&
423
+?? .gitignore
424
+?? done/five
425
+?? dtwo/
426
+EOF
427
+ test_cmp ../status.expect ../status.actual &&
428
+ cat >../trace.expect <<EOF &&
429
+node creation: 0
430
+gitignore invalidation: 1
431
+directory invalidation: 2
432
+opendir: 2
433
+EOF
434
+ test_cmp ../trace.expect ../trace
435
+'
436
+
437
+test_expect_success 'untracked cache correct after status' '
438
+ test-dump-untracked-cache >../actual &&
439
+ cat >../expect <<EOF &&
440
+info/exclude 13263c0978fb9fad16b2d580fb800b6d811c3ff0
441
+core.excludesfile 0000000000000000000000000000000000000000
442
+exclude_per_dir .gitignore
443
+flags 00000006
444
+/ e6fcc8f2ee31bae321d66afd183fcb7237afae6e recurse valid
445
+.gitignore
446
+dtwo/
447
+/done/ 1946f0437f90c5005533cbe1736a6451ca301714 recurse valid
448
+five
449
+/dthree/ 0000000000000000000000000000000000000000 recurse check_only valid
450
+/dtwo/ 0000000000000000000000000000000000000000 recurse check_only valid
451
+two
452
+EOF
453
+ test_cmp ../expect ../actual
454
+'
455
+
456
+test_expect_success 'test sparse status again with untracked cache' '
457
+ avoid_racy &&
458
+ : >../trace &&
459
+ GIT_TRACE_UNTRACKED_STATS="$TRASH_DIRECTORY/trace" \
460
+ git status --porcelain >../status.actual &&
461
+ cat >../status.expect <<EOF &&
462
+?? .gitignore
463
+?? done/five
464
+?? dtwo/
465
+EOF
466
+ test_cmp ../status.expect ../status.actual &&
467
+ cat >../trace.expect <<EOF &&
468
+node creation: 0
469
+gitignore invalidation: 0
470
+directory invalidation: 0
471
+opendir: 0
472
+EOF
473
+ test_cmp ../trace.expect ../trace
474
+'
475
+
476
test_done