If .gitmodules exists in the working tree but is a directory, it would have just tried to use it as if it were a file. On a platform that needs FREAD_READS_DIRECTORIES, this would have been hidden by our own fopen() that pretends as if directory did not exist, so it is a no-op. Just to add some documentation value, make sure we check with file_exists_as_file() instead of file_exists(), the latter of which will be happy as long as the given path exists no matter what it is. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- dir.c | 6 ++++++ dir.h | 1 + submodule-config.c | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dir.c b/dir.c index 73f89f4d8c..d943da93df 100644 --- a/dir.c +++ b/dir.c @@ -3142,6 +3142,12 @@ int file_exists(const char *f) return lstat(f, &sb) == 0; } +int file_exists_as_file(const char *path) +{ + struct stat st; + return lstat(path, &st) == 0 && S_ISREG(st.st_mode); +} + int repo_file_exists(struct repository *repo, const char *path) { if (repo != the_repository) diff --git a/dir.h b/dir.h index 1398a53fb4..3612dbbf9e 100644 --- a/dir.h +++ b/dir.h @@ -475,6 +475,7 @@ void dir_clear(struct dir_struct *dir); int repo_file_exists(struct repository *repo, const char *path); int file_exists(const char *); +int file_exists_as_file(const char *); int is_inside_dir(const char *dir); int dir_inside_of(const char *subdir, const char *dir); diff --git a/submodule-config.c b/submodule-config.c index ec45ea67b9..6c18ae3764 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -801,7 +801,7 @@ static void config_from_gitmodules(config_fn_t fn, struct repository *repo, void char *oidstr = NULL; file = repo_worktree_path(repo, GITMODULES_FILE); - if (file_exists(file)) { + if (file_exists_as_file(file)) { config_source.file = file; } else if (repo_get_oid(repo, GITMODULES_INDEX, &oid) >= 0 || repo_get_oid(repo, GITMODULES_HEAD, &oid) >= 0) { -- 2.45.2-711-gd2c001ca14