Skip to content

Commit 2c521b0

Browse files
vdyegitster
authored andcommitted
status: fix nested sparse directory diff in sparse index
Enable the 'recursive' diff option for the diff executed as part of 'git status'. Without the 'recursive' enabled, 'git status' reports index changes incorrectly when the following conditions were met: * sparse index is enabled * there is a difference between the index and HEAD in a file inside a *subdirectory* of a sparse directory * the sparse directory index entry is *not* expanded in-core Because it is not recursive by default, the diff in 'git status' reports changes only at the level of files and directories that are immediate children of a sparse directory, rather than recursing into directories with changes to identify the modified file(s). As a result, 'git status' reports the immediate subdirectory itself as "modified". Example: $ git init $ mkdir -p sparse/sub $ echo test >sparse/sub/foo $ git add . $ git commit -m "commit 1" $ echo somethingelse >sparse/sub/foo $ git add . $ git commit -a -m "commit 2" $ git sparse-checkout set --cone --sparse-index 'sparse' $ git reset --soft HEAD~1 $ git status On branch master You are in a sparse checkout. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: sparse/sub Enabling the 'recursive' diff option in 'wt_status_collect_changes_index' corrects this issue by allowing the diff to recurse into subdirectories of sparse directories to find modified files. Given the same repository setup as the example above, the corrected result of `git status` is: $ git status On branch master You are in a sparse checkout. Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: sparse/sub/foo Signed-off-by: Victoria Dye <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 287fd17 commit 2c521b0

File tree

2 files changed

+16
-0
lines changed

2 files changed

+16
-0
lines changed

t/t1092-sparse-checkout-compatibility.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,13 @@ test_expect_success 'status with options' '
278278
test_all_match git status --porcelain=v2 -uno
279279
'
280280

281+
test_expect_success 'status with diff in unexpanded sparse directory' '
282+
init_repos &&
283+
test_all_match git checkout rename-base &&
284+
test_all_match git reset --soft rename-out-to-out &&
285+
test_all_match git status --porcelain=v2
286+
'
287+
281288
test_expect_success 'status reports sparse-checkout' '
282289
init_repos &&
283290
git -C sparse-checkout status >full &&

wt-status.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,15 @@ static void wt_status_collect_changes_index(struct wt_status *s)
651651
rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
652652
rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
653653
rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
654+
655+
/*
656+
* The `recursive` option must be enabled to allow the diff to recurse
657+
* into subdirectories of sparse directory index entries. If it is not
658+
* enabled, a subdirectory containing file(s) with changes is reported
659+
* as "modified", rather than the modified files themselves.
660+
*/
661+
rev.diffopt.flags.recursive = 1;
662+
654663
copy_pathspec(&rev.prune_data, &s->pathspec);
655664
run_diff_index(&rev, 1);
656665
object_array_clear(&rev.pending);

0 commit comments

Comments
 (0)