Skip to content

Commit 105e8b0

Browse files
derrickstoleegitster
authored andcommitted
add: fail when adding an untracked sparse file
The add_files() method in builtin/add.c takes a set of untracked files that are being added by the input pathspec and inserts them into the index. If these files are outside of the sparse-checkout cone, then they gain the SKIP_WORKTREE bit at some point. However, this was not checked before inserting into the index, so these files are added even though we want to avoid modifying the index outside of the sparse-checkout cone. Add a check within add_files() for these files and write the advice about files outside of the sparse-checkout cone. This behavior change modifies some existing tests within t1092. These tests intended to document how a user could interact with the existing behavior in place. Many of these tests need to be marked as expecting failure. A future change will allow these tests to pass by adding a flag to 'git add' that allows users to modify index entries outside of the sparse-checkout cone. The 'submodule handling' test is intended to document what happens to directories that contain a submodule when the sparse index is enabled. It is not trying to say that users should be able to add submodules outside of the sparse-checkout cone, so that test can be modified to avoid that operation. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ed49584 commit 105e8b0

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

builtin/add.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ static void check_embedded_repo(const char *path)
443443
static int add_files(struct dir_struct *dir, int flags)
444444
{
445445
int i, exit_status = 0;
446+
struct string_list matched_sparse_paths = STRING_LIST_INIT_NODUP;
446447

447448
if (dir->ignored_nr) {
448449
fprintf(stderr, _(ignore_error));
@@ -456,6 +457,11 @@ static int add_files(struct dir_struct *dir, int flags)
456457
}
457458

458459
for (i = 0; i < dir->nr; i++) {
460+
if (!path_in_sparse_checkout(dir->entries[i]->name, &the_index)) {
461+
string_list_append(&matched_sparse_paths,
462+
dir->entries[i]->name);
463+
continue;
464+
}
459465
if (add_file_to_index(&the_index, dir->entries[i]->name, flags)) {
460466
if (!ignore_add_errors)
461467
die(_("adding files failed"));
@@ -464,6 +470,14 @@ static int add_files(struct dir_struct *dir, int flags)
464470
check_embedded_repo(dir->entries[i]->name);
465471
}
466472
}
473+
474+
if (matched_sparse_paths.nr) {
475+
advise_on_updating_sparse_paths(&matched_sparse_paths);
476+
exit_status = 1;
477+
}
478+
479+
string_list_clear(&matched_sparse_paths, 0);
480+
467481
return exit_status;
468482
}
469483

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,6 @@ test_expect_success 'add, commit, checkout' '
301301
test_all_match git checkout -
302302
'
303303

304-
# NEEDSWORK: This documents current behavior, but is not a desirable
305-
# behavior (untracked files are handled differently than tracked).
306304
test_expect_success 'add outside sparse cone' '
307305
init_repos &&
308306
@@ -312,7 +310,9 @@ test_expect_success 'add outside sparse cone' '
312310
test_sparse_match test_must_fail git add folder1/a &&
313311
grep "Disable or modify the sparsity rules" sparse-checkout-err &&
314312
test_sparse_unstaged folder1/a &&
315-
test_sparse_match git add folder1/newfile
313+
test_sparse_match test_must_fail git add folder1/newfile &&
314+
grep "Disable or modify the sparsity rules" sparse-checkout-err &&
315+
test_sparse_unstaged folder1/newfile
316316
'
317317

318318
test_expect_success 'commit including unstaged changes' '
@@ -343,7 +343,11 @@ test_expect_success 'commit including unstaged changes' '
343343
test_all_match git status --porcelain=v2
344344
'
345345

346-
test_expect_success 'status/add: outside sparse cone' '
346+
# NEEDSWORK: Now that 'git add folder1/new' fails, the changes being
347+
# attempted here fail for the sparse-checkout and sparse-index repos.
348+
# We must enable a way for adding files outside the sparse-checkout
349+
# done, even if it is by an optional flag.
350+
test_expect_failure 'status/add: outside sparse cone' '
347351
init_repos &&
348352
349353
# folder1 is at HEAD, but outside the sparse cone
@@ -368,10 +372,11 @@ test_expect_success 'status/add: outside sparse cone' '
368372
test_sparse_match test_must_fail git add --refresh folder1/a &&
369373
grep "Disable or modify the sparsity rules" sparse-checkout-err &&
370374
test_sparse_unstaged folder1/a &&
375+
test_sparse_match test_must_fail git add folder1/new &&
376+
grep "Disable or modify the sparsity rules" sparse-checkout-err &&
377+
test_sparse_unstaged folder1/new &&
371378
372-
# NEEDSWORK: Adding a newly-tracked file outside the cone succeeds
373-
test_sparse_match git add folder1/new &&
374-
379+
# NEEDSWORK: behavior begins to deviate here.
375380
test_all_match git add . &&
376381
test_all_match git status --porcelain=v2 &&
377382
test_all_match git commit -m folder1/new &&
@@ -527,7 +532,7 @@ test_expect_success 'merge, cherry-pick, and rebase' '
527532
# Right now, users might be using this flow to work through conflicts,
528533
# so any solution should present advice to users who try this sequence
529534
# of commands to follow whatever new method we create.
530-
test_expect_success 'merge with conflict outside cone' '
535+
test_expect_failure 'merge with conflict outside cone' '
531536
init_repos &&
532537
533538
test_all_match git checkout -b merge-tip merge-left &&
@@ -541,12 +546,18 @@ test_expect_success 'merge with conflict outside cone' '
541546
test_all_match git status --porcelain=v2 &&
542547
543548
# 2. Add the file with conflict markers
549+
# NEEDSWORK: Even though the merge conflict removed the
550+
# SKIP_WORKTREE bit from the index entry for folder1/a, we should
551+
# warn that this is a problematic add.
544552
test_all_match git add folder1/a &&
545553
test_all_match git status --porcelain=v2 &&
546554
547555
# 3. Rename the file to another sparse filename and
548556
# accept conflict markers as resolved content.
549557
run_on_all mv folder2/a folder2/z &&
558+
# NEEDSWORK: This mode now fails, because folder2/z is
559+
# outside of the sparse-checkout cone and does not match an
560+
# existing index entry with the SKIP_WORKTREE bit cleared.
550561
test_all_match git add folder2 &&
551562
test_all_match git status --porcelain=v2 &&
552563
@@ -555,7 +566,7 @@ test_expect_success 'merge with conflict outside cone' '
555566
test_all_match git rev-parse HEAD^{tree}
556567
'
557568

558-
test_expect_success 'cherry-pick/rebase with conflict outside cone' '
569+
test_expect_failure 'cherry-pick/rebase with conflict outside cone' '
559570
init_repos &&
560571
561572
for OPERATION in cherry-pick rebase
@@ -572,11 +583,17 @@ test_expect_success 'cherry-pick/rebase with conflict outside cone' '
572583
test_all_match git status --porcelain=v2 &&
573584
574585
# 2. Add the file with conflict markers
586+
# NEEDSWORK: Even though the merge conflict removed the
587+
# SKIP_WORKTREE bit from the index entry for folder1/a, we should
588+
# warn that this is a problematic add.
575589
test_all_match git add folder1/a &&
576590
test_all_match git status --porcelain=v2 &&
577591
578592
# 3. Rename the file to another sparse filename and
579593
# accept conflict markers as resolved content.
594+
# NEEDSWORK: This mode now fails, because folder2/z is
595+
# outside of the sparse-checkout cone and does not match an
596+
# existing index entry with the SKIP_WORKTREE bit cleared.
580597
run_on_all mv folder2/a folder2/z &&
581598
test_all_match git add folder2 &&
582599
test_all_match git status --porcelain=v2 &&
@@ -654,6 +671,7 @@ test_expect_success 'clean' '
654671
test_expect_success 'submodule handling' '
655672
init_repos &&
656673
674+
test_sparse_match git sparse-checkout add modules &&
657675
test_all_match mkdir modules &&
658676
test_all_match touch modules/a &&
659677
test_all_match git add modules &&
@@ -663,6 +681,7 @@ test_expect_success 'submodule handling' '
663681
test_all_match git commit -m "add submodule" &&
664682
665683
# having a submodule prevents "modules" from collapse
684+
test_sparse_match git sparse-checkout set deep/deeper1 &&
666685
test-tool -C sparse-index read-cache --table >cache &&
667686
grep "100644 blob .* modules/a" cache &&
668687
grep "160000 commit $(git -C initial-repo rev-parse HEAD) modules/sub" cache

0 commit comments

Comments
 (0)