This regression is introduced by f58dbf23c3, which calls check_work_tree_entity in run_diff_files. While check_work_tree_entity treats submodule not checked out as non stagable which causes that diff-files shows these submodules as deleted. check_work_tree_entity considers a worktree entity having two statuses: stagable and inexistent. Actually, there is a 3rd status: a submodule entity can be existent but not stagable (for example, empty directory for non-checked-out submodule) This patch redesigns the return value of check_work_tree_entity to consider both the 3 statuses. Signed-off-by: Ping Yin <pkufranky@xxxxxxxxx> --- diff-lib.c | 22 +++++++++++++--------- 1 files changed, 13 insertions(+), 9 deletions(-) diff --git a/diff-lib.c b/diff-lib.c index cfd629d..72c2a7b 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -337,25 +337,29 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv) } return run_diff_files(revs, options); } + +#define ENT_STAGABLE 1 +#define ENT_INEXISTENT 2 +#define ENT_NOTGITDIR 3 /* Existent but not stagable (not a git dir) */ /* - * See if work tree has an entity that can be staged. Return 0 if so, - * return 1 if not and return -1 if error. + * Check the status of a work tree entity + * Return ENT_{STAGABLE,INEXISTENT,NOTGITDIR} or -1 if error */ static int check_work_tree_entity(const struct cache_entry *ce, struct stat *st, char *symcache) { if (lstat(ce->name, st) < 0) { if (errno != ENOENT && errno != ENOTDIR) return -1; - return 1; + return ENT_INEXISTENT; } if (has_symlink_leading_path(ce->name, symcache)) - return 1; + return ENT_INEXISTENT; if (S_ISDIR(st->st_mode)) { unsigned char sub[20]; if (resolve_gitlink_ref(ce->name, "HEAD", sub)) - return 1; + return ENT_NOTGITDIR; } - return 0; + return ENT_STAGABLE; } int run_diff_files(struct rev_info *revs, unsigned int option) @@ -403,7 +407,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) sizeof(struct combine_diff_parent)*5); changed = check_work_tree_entity(ce, &st, symcache); - if (!changed) + if (changed != ENT_INEXISTENT) dpath->mode = ce_mode_from_stat(ce, st.st_mode); else { if (changed < 0) { @@ -467,7 +471,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option) continue; changed = check_work_tree_entity(ce, &st, symcache); - if (changed) { + if (changed == ENT_INEXISTENT) { if (changed < 0) { perror(ce->name); continue; @@ -527,7 +531,7 @@ static int get_stat_data(struct cache_entry *ce, changed = check_work_tree_entity(ce, &st, cbdata->symcache); if (changed < 0) return -1; - else if (changed) { + else if (changed == ENT_INEXISTENT) { if (match_missing) { *sha1p = sha1; *modep = mode; -- 1.5.5.1.116.ge4b9c.dirty -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html