]> git.ipfire.org Git - thirdparty/git.git/commitdiff
dir: introduce readdir_skip_dot_and_dotdot() helper
authorElijah Newren <newren@gmail.com>
Thu, 27 May 2021 04:53:56 +0000 (04:53 +0000)
committerJunio C Hamano <gitster@pobox.com>
Thu, 27 May 2021 05:02:37 +0000 (14:02 +0900)
Many places in the code were doing
    while ((d = readdir(dir)) != NULL) {
        if (is_dot_or_dotdot(d->d_name))
            continue;
        ...process d...
    }
Introduce a readdir_skip_dot_and_dotdot() helper to make that a one-liner:
    while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
        ...process d...
    }

This helper particularly simplifies checks for empty directories.

Also use this helper in read_cached_dir() so that our statistics are
consistent across platforms.  (In other words, read_cached_dir() should
have been using is_dot_or_dotdot() and skipping such entries, but did
not and left it to treat_path() to detect and mark such entries as
path_none.)

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/clean.c
builtin/worktree.c
diff-no-index.c
dir.c
dir.h
entry.c
notes-merge.c
object-file.c
packfile.c
rerere.c
worktree.c

index 995053b79173e1eab3d4ce567557c37893f4214a..a1a57476153b86ea304cf5f807c4f4510091369d 100644 (file)
@@ -189,10 +189,8 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
        strbuf_complete(path, '/');
 
        len = path->len;
-       while ((e = readdir(dir)) != NULL) {
+       while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL) {
                struct stat st;
-               if (is_dot_or_dotdot(e->d_name))
-                       continue;
 
                strbuf_setlen(path, len);
                strbuf_addstr(path, e->d_name);
index 1cd5c2016e3f90f4f2da15bad4a1be7038db327b..e081ca9befd141ec2766261ba9350b2e4df9a819 100644 (file)
@@ -118,10 +118,8 @@ static void prune_worktrees(void)
        struct dirent *d;
        if (!dir)
                return;
-       while ((d = readdir(dir)) != NULL) {
+       while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
                char *path;
-               if (is_dot_or_dotdot(d->d_name))
-                       continue;
                strbuf_reset(&reason);
                if (should_prune_worktree(d->d_name, &reason, &path, expire))
                        prune_worktree(d->d_name, reason.buf);
index 7814eabfe0289125fd50d4f3b0bba06fe08ccac4..e5cc878371430b2023606f042862baac37760b6f 100644 (file)
@@ -26,9 +26,8 @@ static int read_directory_contents(const char *path, struct string_list *list)
        if (!(dir = opendir(path)))
                return error("Could not open directory %s", path);
 
-       while ((e = readdir(dir)))
-               if (!is_dot_or_dotdot(e->d_name))
-                       string_list_insert(list, e->d_name);
+       while ((e = readdir_skip_dot_and_dotdot(dir)))
+               string_list_insert(list, e->d_name);
 
        closedir(dir);
        return 0;
diff --git a/dir.c b/dir.c
index ff004b298b2a3f59f2c4e738de662aaea21c62e0..b909cf9b03da8adcd60d3e7f86c52312f2ff2a0f 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -59,6 +59,17 @@ void dir_init(struct dir_struct *dir)
        memset(dir, 0, sizeof(*dir));
 }
 
+struct dirent *readdir_skip_dot_and_dotdot(DIR *dirp)
+{
+       struct dirent *e;
+
+       while ((e = readdir(dirp)) != NULL) {
+               if (!is_dot_or_dotdot(e->d_name))
+                       break;
+       }
+       return e;
+}
+
 int count_slashes(const char *s)
 {
        int cnt = 0;
@@ -2332,7 +2343,7 @@ static int read_cached_dir(struct cached_dir *cdir)
        struct dirent *de;
 
        if (cdir->fdir) {
-               de = readdir(cdir->fdir);
+               de = readdir_skip_dot_and_dotdot(cdir->fdir);
                if (!de) {
                        cdir->d_name = NULL;
                        cdir->d_type = DT_UNKNOWN;
@@ -2931,11 +2942,9 @@ int is_empty_dir(const char *path)
        if (!dir)
                return 0;
 
-       while ((e = readdir(dir)) != NULL)
-               if (!is_dot_or_dotdot(e->d_name)) {
-                       ret = 0;
-                       break;
-               }
+       e = readdir_skip_dot_and_dotdot(dir);
+       if (e)
+               ret = 0;
 
        closedir(dir);
        return ret;
@@ -2975,10 +2984,8 @@ static int remove_dir_recurse(struct strbuf *path, int flag, int *kept_up)
        strbuf_complete(path, '/');
 
        len = path->len;
-       while ((e = readdir(dir)) != NULL) {
+       while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL) {
                struct stat st;
-               if (is_dot_or_dotdot(e->d_name))
-                       continue;
 
                strbuf_setlen(path, len);
                strbuf_addstr(path, e->d_name);
diff --git a/dir.h b/dir.h
index 70c750e3053ded3114cc2b22287afbb53350002c..6b3fac0829452a43150170d5f1ad21b0bf20cc2e 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -342,6 +342,8 @@ struct dir_struct {
        unsigned visited_directories;
 };
 
+struct dirent *readdir_skip_dot_and_dotdot(DIR *dirp);
+
 /*Count the number of slashes for string s*/
 int count_slashes(const char *s);
 
diff --git a/entry.c b/entry.c
index 7b9f43716f76e6e7a701966045429b263cfb691e..e3d3add300078da88f6fc5c3a0ed17c82f062213 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -56,12 +56,9 @@ static void remove_subtree(struct strbuf *path)
 
        if (!dir)
                die_errno("cannot opendir '%s'", path->buf);
-       while ((de = readdir(dir)) != NULL) {
+       while ((de = readdir_skip_dot_and_dotdot(dir)) != NULL) {
                struct stat st;
 
-               if (is_dot_or_dotdot(de->d_name))
-                       continue;
-
                strbuf_addch(path, '/');
                strbuf_addstr(path, de->d_name);
                if (lstat(path->buf, &st))
index d2771fa3d43ced4980a9c94af2ee8d5f92caa168..e9d6f86d3428c36a7430aae889672d584a8a8961 100644 (file)
@@ -695,13 +695,10 @@ int notes_merge_commit(struct notes_merge_options *o,
 
        strbuf_addch(&path, '/');
        baselen = path.len;
-       while ((e = readdir(dir)) != NULL) {
+       while ((e = readdir_skip_dot_and_dotdot(dir)) != NULL) {
                struct stat st;
                struct object_id obj_oid, blob_oid;
 
-               if (is_dot_or_dotdot(e->d_name))
-                       continue;
-
                if (get_oid_hex(e->d_name, &obj_oid)) {
                        if (o->verbosity >= 3)
                                printf("Skipping non-SHA1 entry '%s%s'\n",
index 624af408cdcd2aec95b1f54882a0c8027a60c723..77bdcfd21bc8d1798a3d4ee5fdee27d0be7b3c82 100644 (file)
@@ -2304,10 +2304,8 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr,
        strbuf_addch(path, '/');
        baselen = path->len;
 
-       while ((de = readdir(dir))) {
+       while ((de = readdir_skip_dot_and_dotdot(dir))) {
                size_t namelen;
-               if (is_dot_or_dotdot(de->d_name))
-                       continue;
 
                namelen = strlen(de->d_name);
                strbuf_setlen(path, baselen);
index ea29f4ba77356049ea80bcf9b5276d8781910d7c..463d61c87761c594a05781f4558f506a6640cba2 100644 (file)
@@ -813,10 +813,7 @@ void for_each_file_in_pack_dir(const char *objdir,
        }
        strbuf_addch(&path, '/');
        dirnamelen = path.len;
-       while ((de = readdir(dir)) != NULL) {
-               if (is_dot_or_dotdot(de->d_name))
-                       continue;
-
+       while ((de = readdir_skip_dot_and_dotdot(dir)) != NULL) {
                strbuf_setlen(&path, dirnamelen);
                strbuf_addstr(&path, de->d_name);
 
index dee60dc6df6324857904f07a3edb7355afacec45..d83d58df4fbc930b756395a8a99a77be4c1e598f 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -1190,13 +1190,11 @@ void rerere_gc(struct repository *r, struct string_list *rr)
        if (!dir)
                die_errno(_("unable to open rr-cache directory"));
        /* Collect stale conflict IDs ... */
-       while ((e = readdir(dir))) {
+       while ((e = readdir_skip_dot_and_dotdot(dir))) {
                struct rerere_dir *rr_dir;
                struct rerere_id id;
                int now_empty;
 
-               if (is_dot_or_dotdot(e->d_name))
-                       continue;
                if (!is_rr_cache_dirname(e->d_name))
                        continue; /* or should we remove e->d_name? */
 
index f35ac40a84a5133d86aa2b92f10fe69ec13e2241..237517baee675631d50020ba0d75853881010f6d 100644 (file)
@@ -128,10 +128,8 @@ struct worktree **get_worktrees(void)
        dir = opendir(path.buf);
        strbuf_release(&path);
        if (dir) {
-               while ((d = readdir(dir)) != NULL) {
+               while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
                        struct worktree *linked = NULL;
-                       if (is_dot_or_dotdot(d->d_name))
-                               continue;
 
                        if ((linked = get_linked_worktree(d->d_name))) {
                                ALLOC_GROW(list, counter + 1, alloc);
@@ -486,13 +484,9 @@ int submodule_uses_worktrees(const char *path)
        if (!dir)
                return 0;
 
-       while ((d = readdir(dir)) != NULL) {
-               if (is_dot_or_dotdot(d->d_name))
-                       continue;
-
+       d = readdir_skip_dot_and_dotdot(dir);
+       if (d != NULL)
                ret = 1;
-               break;
-       }
        closedir(dir);
        return ret;
 }