Skip to content

Commit 5911878

Browse files
committed
iterator: don't stat directories
1 parent bb2a754 commit 5911878

1 file changed

Lines changed: 43 additions & 36 deletions

File tree

src/iterator.c

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77

88
#include "iterator.h"
99

10+
#include <dirent.h>
11+
#include <sys/stat.h>
12+
#include <sys/types.h>
13+
#include <unistd.h>
14+
1015
#include "tree.h"
1116
#include "index.h"
1217

@@ -1337,7 +1342,8 @@ static int filesystem_iterator_frame_push(
13371342
filesystem_iterator_entry *entry;
13381343
struct stat statbuf;
13391344
size_t path_len;
1340-
int error;
1345+
int error = 0;
1346+
bool submodule = false;
13411347

13421348
if (iter->frames.size == FILESYSTEM_MAX_DEPTH) {
13431349
git_error_set(GIT_ERROR_REPOSITORY,
@@ -1402,52 +1408,53 @@ static int filesystem_iterator_frame_push(
14021408
iter, frame_entry, path, path_len))
14031409
continue;
14041410

1411+
if (filesystem_iterator_is_dot_git(iter, path, path_len))
1412+
continue;
1413+
14051414
/* TODO: don't need to stat if assume unchanged for this path and
14061415
* we have an index, we can just copy the data out of it.
14071416
*/
14081417

1409-
if ((error = git_path_diriter_stat(&statbuf, &diriter)) < 0) {
1410-
/* file was removed between readdir and lstat */
1411-
if (error == GIT_ENOTFOUND)
1412-
continue;
1413-
1414-
/* treat the file as unreadable */
1415-
memset(&statbuf, 0, sizeof(statbuf));
1416-
statbuf.st_mode = GIT_FILEMODE_UNREADABLE;
1417-
1418-
error = 0;
1419-
}
1418+
if (diriter.d_type == DT_DIR &&
1419+
!(error = filesystem_iterator_is_submodule(&submodule, iter, path, path_len)) &&
1420+
!submodule) {
1421+
// It's a directory, no need to lstat it.
1422+
statbuf.st_mode = S_IFDIR;
1423+
} else if (error < 0) {
1424+
goto done;
1425+
} else {
1426+
if ((error = git_path_diriter_stat(&statbuf, &diriter)) < 0) {
1427+
/* file was removed between readdir and lstat */
1428+
if (error == GIT_ENOTFOUND) continue;
14201429

1421-
iter->base.stat_calls++;
1430+
/* treat the file as unreadable */
1431+
memset(&statbuf, 0, sizeof(statbuf));
1432+
statbuf.st_mode = GIT_FILEMODE_UNREADABLE;
14221433

1423-
/* Ignore wacky things in the filesystem */
1424-
if (!S_ISDIR(statbuf.st_mode) &&
1425-
!S_ISREG(statbuf.st_mode) &&
1426-
!S_ISLNK(statbuf.st_mode) &&
1427-
statbuf.st_mode != GIT_FILEMODE_UNREADABLE)
1428-
continue;
1429-
1430-
if (filesystem_iterator_is_dot_git(iter, path, path_len))
1431-
continue;
1434+
error = 0;
1435+
}
1436+
iter->base.stat_calls++;
14321437

1433-
/* convert submodules to GITLINK and remove trailing slashes */
1434-
if (S_ISDIR(statbuf.st_mode)) {
1435-
bool submodule = false;
1438+
/* Ignore wacky things in the filesystem */
1439+
if (!S_ISDIR(statbuf.st_mode) && !S_ISREG(statbuf.st_mode) && !S_ISLNK(statbuf.st_mode) &&
1440+
statbuf.st_mode != GIT_FILEMODE_UNREADABLE)
1441+
continue;
14361442

1437-
if ((error = filesystem_iterator_is_submodule(&submodule,
1438-
iter, path, path_len)) < 0)
1439-
goto done;
1443+
/* Ensure that the pathlist entry lines up with what we expected */
1444+
if (dir_expected && !S_ISDIR(statbuf.st_mode)) continue;
14401445

1441-
if (submodule)
1442-
statbuf.st_mode = GIT_FILEMODE_COMMIT;
1446+
/* convert submodules to GITLINK and remove trailing slashes */
1447+
if (S_ISDIR(statbuf.st_mode)) {
1448+
if (!submodule) {
1449+
if ((error = filesystem_iterator_is_submodule(&submodule, iter, path, path_len)) < 0)
1450+
goto done;
1451+
}
1452+
if (submodule) statbuf.st_mode = GIT_FILEMODE_COMMIT;
1453+
}
14431454
}
14441455

1445-
/* Ensure that the pathlist entry lines up with what we expected */
1446-
else if (dir_expected)
1447-
continue;
1448-
1449-
if ((error = filesystem_iterator_entry_init(&entry,
1450-
iter, new_frame, path, path_len, &statbuf, pathlist_match)) < 0)
1456+
if ((error = filesystem_iterator_entry_init(&entry, iter, new_frame, path, path_len, &statbuf,
1457+
pathlist_match)) < 0)
14511458
goto done;
14521459

14531460
git_vector_insert(&new_frame->entries, entry);

0 commit comments

Comments
 (0)