File add-readdir_skip_dot_and_dotdot.patch of Package git.34091
From 906fc557b70b2b2995785c9b37e212d2f86b469e Mon Sep 17 00:00:00 2001
From: Elijah Newren <newren@gmail.com>
Date: Thu, 27 May 2021 04:53:56 +0000
Subject: [PATCH] dir: introduce readdir_skip_dot_and_dotdot() helper
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 | 4 +---
builtin/worktree.c | 4 +---
diff-no-index.c | 5 ++---
dir.c | 25 ++++++++++++++++---------
dir.h | 2 ++
entry.c | 5 +----
notes-merge.c | 5 +----
object-file.c | 4 +---
packfile.c | 5 +----
rerere.c | 4 +---
worktree.c | 12 +++---------
11 files changed, 30 insertions(+), 45 deletions(-)
Index: git-2.26.2/builtin/clean.c
===================================================================
--- git-2.26.2.orig/builtin/clean.c
+++ git-2.26.2/builtin/clean.c
@@ -188,10 +188,8 @@ static int remove_dirs(struct strbuf *pa
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: git-2.26.2/builtin/worktree.c
===================================================================
--- git-2.26.2.orig/builtin/worktree.c
+++ git-2.26.2/builtin/worktree.c
@@ -140,9 +140,7 @@ static void prune_worktrees(void)
struct dirent *d;
if (!dir)
return;
- while ((d = readdir(dir)) != NULL) {
- if (is_dot_or_dotdot(d->d_name))
- continue;
+ while ((d = readdir_skip_dot_and_dotdot(dir)) != NULL) {
strbuf_reset(&reason);
if (!prune_worktree(d->d_name, &reason))
continue;
Index: git-2.26.2/diff-no-index.c
===================================================================
--- git-2.26.2.orig/diff-no-index.c
+++ git-2.26.2/diff-no-index.c
@@ -26,9 +26,8 @@ static int read_directory_contents(const
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;
Index: git-2.26.2/dir.c
===================================================================
--- git-2.26.2.orig/dir.c
+++ git-2.26.2/dir.c
@@ -54,6 +54,17 @@ static enum path_treatment read_director
static int resolve_dtype(int dtype, struct index_state *istate,
const char *path, int len);
+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;
@@ -2156,7 +2167,7 @@ static int read_cached_dir(struct cached
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;
@@ -2782,11 +2793,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;
@@ -2826,10 +2835,8 @@ static int remove_dir_recurse(struct str
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: git-2.26.2/dir.h
===================================================================
--- git-2.26.2.orig/dir.h
+++ git-2.26.2/dir.h
@@ -339,6 +339,8 @@ struct dir_struct {
unsigned unmanaged_exclude_files;
};
+struct dirent *readdir_skip_dot_and_dotdot(DIR *dirp);
+
/*Count the number of slashes for string s*/
int count_slashes(const char *s);
Index: git-2.26.2/entry.c
===================================================================
--- git-2.26.2.orig/entry.c
+++ git-2.26.2/entry.c
@@ -56,12 +56,9 @@ static void remove_subtree(struct strbuf
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: git-2.26.2/notes-merge.c
===================================================================
--- git-2.26.2.orig/notes-merge.c
+++ git-2.26.2/notes-merge.c
@@ -695,13 +695,10 @@ int notes_merge_commit(struct notes_merg
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: git-2.26.2/packfile.c
===================================================================
--- git-2.26.2.orig/packfile.c
+++ git-2.26.2/packfile.c
@@ -817,10 +817,7 @@ void for_each_file_in_pack_dir(const cha
}
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: git-2.26.2/rerere.c
===================================================================
--- git-2.26.2.orig/rerere.c
+++ git-2.26.2/rerere.c
@@ -1198,13 +1198,11 @@ void rerere_gc(struct repository *r, str
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;
rr_dir = find_rerere_dir(e->d_name);
if (!rr_dir)
continue; /* or should we remove e->d_name? */
Index: git-2.26.2/worktree.c
===================================================================
--- git-2.26.2.orig/worktree.c
+++ git-2.26.2/worktree.c
@@ -146,10 +146,8 @@ struct worktree **get_worktrees(unsigned
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);
@@ -488,13 +486,9 @@ int submodule_uses_worktrees(const char
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;
}