Skip to content

Commit 9eb00af

Browse files
derrickstoleegitster
authored andcommitted
diff-lib: handle index diffs with sparse dirs
While comparing an index to a tree, we may see a sparse directory entry. In this case, we should compare that portion of the tree to the tree represented by that entry. This could include a new tree which needs to be expanded to a full list of added files. It could also include an existing tree, in which case all of the changes inside are important to describe, including the modifications, additions, and deletions. Note that the case where the tree has a path and the index does not remains identical to before: the lack of a cache entry is the same with a sparse index. Use diff_tree_oid() appropriately to compute the diff. Reviewed-by: Elijah Newren <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 69bdbdb commit 9eb00af

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

diff-lib.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,11 @@ static void show_new_file(struct rev_info *revs,
325325
unsigned dirty_submodule = 0;
326326
struct index_state *istate = revs->diffopt.repo->index;
327327

328+
if (new_file && S_ISSPARSEDIR(new_file->ce_mode)) {
329+
diff_tree_oid(NULL, &new_file->oid, new_file->name, &revs->diffopt);
330+
return;
331+
}
332+
328333
/*
329334
* New file in the index: it might actually be different in
330335
* the working tree.
@@ -347,6 +352,20 @@ static int show_modified(struct rev_info *revs,
347352
unsigned dirty_submodule = 0;
348353
struct index_state *istate = revs->diffopt.repo->index;
349354

355+
assert(S_ISSPARSEDIR(old_entry->ce_mode) ==
356+
S_ISSPARSEDIR(new_entry->ce_mode));
357+
358+
/*
359+
* If both are sparse directory entries, then expand the
360+
* modifications to the file level. If only one was a sparse
361+
* directory, then they appear as an add and delete instead of
362+
* a modification.
363+
*/
364+
if (S_ISSPARSEDIR(new_entry->ce_mode)) {
365+
diff_tree_oid(&old_entry->oid, &new_entry->oid, new_entry->name, &revs->diffopt);
366+
return 0;
367+
}
368+
350369
if (get_stat_data(istate, new_entry, &oid, &mode, cached, match_missing,
351370
&dirty_submodule, &revs->diffopt) < 0) {
352371
if (report_missing)

0 commit comments

Comments
 (0)