Skip to content

Commit e52594f

Browse files
committed
push ignore frames lazily
1 parent 4004ece commit e52594f

File tree

1 file changed

+31
-15
lines changed

1 file changed

+31
-15
lines changed

src/iterator.c

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,14 +1128,14 @@ static int filesystem_iterator_is_submodule(
11281128

11291129
static void filesystem_iterator_frame_push_ignores(
11301130
filesystem_iterator *iter,
1131-
filesystem_iterator_entry *frame_entry,
1131+
filesystem_iterator_frame *previous_frame,
11321132
filesystem_iterator_frame *new_frame)
11331133
{
1134-
filesystem_iterator_frame *previous_frame;
1135-
const char *path = frame_entry ? frame_entry->path : "";
1136-
1137-
if (!iterator__honor_ignores(&iter->base))
1138-
return;
1134+
const char* path = "";
1135+
if (previous_frame) {
1136+
path = filesystem_iterator_current_entry(previous_frame)->path;
1137+
assert(path && *path);
1138+
}
11391139

11401140
if (git_ignore__lookup(&new_frame->is_ignored,
11411141
&iter->ignores, path, GIT_DIR_FLAG_TRUE) < 0) {
@@ -1144,27 +1144,31 @@ static void filesystem_iterator_frame_push_ignores(
11441144
}
11451145

11461146
/* if this is not the top level directory... */
1147-
if (frame_entry) {
1147+
if (previous_frame) {
11481148
const char *relative_path;
11491149

1150-
previous_frame = filesystem_iterator_parent_frame(iter);
1151-
11521150
/* push new ignores for files in this directory */
1153-
relative_path = frame_entry->path + previous_frame->path_len;
1151+
relative_path = path + previous_frame->path_len;
11541152

11551153
/* inherit ignored from parent if no rule specified */
11561154
if (new_frame->is_ignored <= GIT_IGNORE_NOTFOUND)
11571155
new_frame->is_ignored = previous_frame->is_ignored;
11581156

11591157
git_ignore__push_dir(&iter->ignores, relative_path);
11601158
}
1159+
1160+
assert((size_t)iter->ignores.depth <= iter->frames.size);
11611161
}
11621162

11631163
static void filesystem_iterator_frame_pop_ignores(
11641164
filesystem_iterator *iter)
11651165
{
1166-
if (iterator__honor_ignores(&iter->base))
1167-
git_ignore__pop_dir(&iter->ignores);
1166+
if (iterator__honor_ignores(&iter->base)) {
1167+
assert((size_t)iter->ignores.depth <= iter->frames.size + 1);
1168+
if ((size_t)iter->ignores.depth == iter->frames.size + 1) {
1169+
git_ignore__pop_dir(&iter->ignores);
1170+
}
1171+
}
11681172
}
11691173

11701174
GIT_INLINE(bool) filesystem_iterator_examine_path(
@@ -1335,6 +1339,8 @@ static int filesystem_iterator_frame_push(
13351339
size_t path_len;
13361340
int error;
13371341

1342+
assert(!frame_entry == !iter->frames.size);
1343+
13381344
if (iter->frames.size == FILESYSTEM_MAX_DEPTH) {
13391345
git_error_set(GIT_ERROR_REPOSITORY,
13401346
"directory nesting too deep (%"PRIuZ")", iter->frames.size);
@@ -1345,6 +1351,7 @@ static int filesystem_iterator_frame_push(
13451351
GIT_ERROR_CHECK_ALLOC(new_frame);
13461352

13471353
memset(new_frame, 0, sizeof(filesystem_iterator_frame));
1354+
new_frame->is_ignored = GIT_IGNORE_UNCHECKED;
13481355

13491356
if (frame_entry)
13501357
git_buf_joinpath(&root, iter->root, frame_entry->path);
@@ -1373,9 +1380,6 @@ static int filesystem_iterator_frame_push(
13731380

13741381
git_pool_init(&new_frame->entry_pool, 1);
13751382

1376-
/* check if this directory is ignored */
1377-
filesystem_iterator_frame_push_ignores(iter, frame_entry, new_frame);
1378-
13791383
while ((error = git_path_diriter_next(&diriter)) == 0) {
13801384
iterator_pathlist_search_t pathlist_match = ITERATOR_PATHLIST_FULL;
13811385
bool dir_expected = false;
@@ -1693,9 +1697,21 @@ GIT_INLINE(git_dir_flag) entry_dir_flag(git_index_entry *entry)
16931697

16941698
static void filesystem_iterator_update_ignored(filesystem_iterator *iter)
16951699
{
1700+
size_t i;
16961701
filesystem_iterator_frame *frame;
16971702
git_dir_flag dir_flag = entry_dir_flag(&iter->entry);
16981703

1704+
for (i = iter->frames.size;
1705+
i && iter->frames.ptr[i - 1].is_ignored == GIT_IGNORE_UNCHECKED;
1706+
--i) {
1707+
// empty body
1708+
}
1709+
1710+
for (; i != iter->frames.size; ++i) {
1711+
frame = iter->frames.ptr + i;
1712+
filesystem_iterator_frame_push_ignores(iter, i ? frame - 1 : NULL, frame);
1713+
}
1714+
16991715
if (git_ignore__lookup(&iter->current_is_ignored,
17001716
&iter->ignores, iter->entry.path, dir_flag) < 0) {
17011717
git_error_clear();

0 commit comments

Comments
 (0)