Download raw body.
Workflow question, maybe bug or unclear usage.
On Tue, Jan 25, 2022 at 11:27:59PM +0100, Christian Weisgerber wrote: > Christian Weisgerber: > > > > For me, using `got checkout` on an NFS share, causes `got status` to > > > report all directories in the work tree with the bogus *?* status as below: > > > > FWIW, I can reproduce this. > > A guess would be that status_new() needs to call got_path_dirent_type() > and not rely on dirent->d_type, which is DT_UNKNOWN for all entries > on NFS. > Yes, I missed applying the DT_UKNOWN workaround in this case. This patch fixes the issue. ok? diff 4362cf9c24c2ad037cda602ae688bef54869f793 /home/stsp/src/got blob - 71a058b11b7499d2dd17a72a9d69aafdb49f8874 file + lib/fileindex.c --- lib/fileindex.c +++ lib/fileindex.c @@ -1022,28 +1022,15 @@ walk_dir(struct got_pathlist_entry **next, struct got_ struct dirent *de = dle->data; DIR *subdir = NULL; int subdirfd = -1; - int type; *next = NULL; - if (de->d_type == DT_UNKNOWN) { - /* Occurs on NFS mounts without "readdir plus" RPC. */ - char *dir_path; - if (asprintf(&dir_path, "%s/%s", rootpath, path) == -1) - return got_error_from_errno("asprintf"); - err = got_path_dirent_type(&type, dir_path, de); - free(dir_path); - if (err) - return err; - } else - type = de->d_type; - /* Must traverse ignored directories if they contain tracked files. */ - if (type == DT_DIR && ignore && + if (de->d_type == DT_DIR && ignore && have_tracked_file_in_dir(fileindex, path)) ignore = 0; - if (type == DT_DIR && !ignore) { + if (de->d_type == DT_DIR && !ignore) { char *subpath; char *subdirpath; struct got_pathlist_head subdirlist; @@ -1099,6 +1086,28 @@ walk_dir(struct got_pathlist_entry **next, struct got_ } static const struct got_error * +dirent_type_fixup(struct dirent *de, const char *rootpath, const char *path) +{ + const struct got_error *err; + char *dir_path; + int type; + + if (de->d_type != DT_UNKNOWN) + return NULL; + + /* DT_UNKNOWN occurs on NFS mounts without "readdir plus" RPC. */ + if (asprintf(&dir_path, "%s/%s", rootpath, path) == -1) + return got_error_from_errno("asprintf"); + err = got_path_dirent_type(&type, dir_path, de); + free(dir_path); + if (err) + return err; + + de->d_type = type; + return NULL; +} + +static const struct got_error * diff_fileindex_dir(struct got_fileindex *fileindex, struct got_fileindex_entry **ie, struct got_pathlist_head *dirlist, int dirfd, const char *rootpath, const char *path, @@ -1123,6 +1132,9 @@ diff_fileindex_dir(struct got_fileindex *fileindex, char *de_path; int cmp; de = dle->data; + err = dirent_type_fixup(de, rootpath, path); + if (err) + break; if (asprintf(&de_path, "%s/%s", path, de->d_name) == -1) { err = got_error_from_errno("asprintf"); @@ -1162,6 +1174,9 @@ diff_fileindex_dir(struct got_fileindex *fileindex, *ie = walk_fileindex(fileindex, *ie); } else if (dle) { de = dle->data; + err = dirent_type_fixup(de, rootpath, path); + if (err) + break; err = cb->diff_new(&ignore, cb_arg, de, path, dirfd); if (err) break;
Workflow question, maybe bug or unclear usage.