diff options
author | Russell Belfer <rb@github.com> | 2013-03-13 14:59:51 -0700 |
---|---|---|
committer | Russell Belfer <rb@github.com> | 2013-03-13 14:59:51 -0700 |
commit | bbb1364671b1a111e4ba9bd6e34e016768306da4 (patch) | |
tree | be2087cb16de9c9a7552d3ac251accf0159cebb6 /tests-clar/repo | |
parent | ad003763ccb39c0e59f5c1d8372a202541a9049e (diff) | |
download | libgit2-bbb1364671b1a111e4ba9bd6e34e016768306da4.tar.gz |
Fix workdir iterator bugs
This fixes two bugs with the workdir iterator depth check: first
that the depth was not being decremented and second that empty
directories were counting against the depth even though a frame
was not being created for them.
This also fixes a bug with the ENOTFOUND return code for workdir
iterators when you attempt to advance_into an empty directory.
Actually, that works correctly, but it was incorrectly being
propogated into regular advance() calls in some circumstances.
Added new tests for the above that create a huge hierarchy on
the fly and try using the workdir iterator to traverse it.
Diffstat (limited to 'tests-clar/repo')
-rw-r--r-- | tests-clar/repo/iterator.c | 69 |
1 files changed, 65 insertions, 4 deletions
diff --git a/tests-clar/repo/iterator.c b/tests-clar/repo/iterator.c index 00123196b..9e1f09881 100644 --- a/tests-clar/repo/iterator.c +++ b/tests-clar/repo/iterator.c @@ -1,6 +1,7 @@ #include "clar_libgit2.h" #include "iterator.h" #include "repository.h" +#include "fileops.h" #include <stdarg.h> static git_repository *g_repo; @@ -23,7 +24,7 @@ static void expect_iterator_items( const char **expected_total_paths) { const git_index_entry *entry; - int count; + int count, error; int no_trees = !(git_iterator_flags(i) & GIT_ITERATOR_INCLUDE_TREES); bool v = false; @@ -86,9 +87,15 @@ static void expect_iterator_items( cl_assert(entry->mode != GIT_FILEMODE_TREE); } - if (entry->mode == GIT_FILEMODE_TREE) - cl_git_pass(git_iterator_advance_into(&entry, i)); - else + if (entry->mode == GIT_FILEMODE_TREE) { + error = git_iterator_advance_into(&entry, i); + + /* could return NOTFOUND if directory is empty */ + cl_assert(!error || error == GIT_ENOTFOUND); + + if (error == GIT_ENOTFOUND) + cl_git_pass(git_iterator_advance(&entry, i)); + } else cl_git_pass(git_iterator_advance(&entry, i)); if (++count > expected_total) @@ -745,3 +752,57 @@ void test_repo_iterator__workdir_icase(void) expect_iterator_items(i, 1, NULL, 6, NULL); git_iterator_free(i); } + +void test_repo_iterator__workdir_depth(void) +{ + int i, j; + git_iterator *iter; + char buf[64]; + + g_repo = cl_git_sandbox_init("icase"); + + for (i = 0; i < 10; ++i) { + p_snprintf(buf, sizeof(buf), "icase/dir%02d", i); + cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH)); + + if (i % 2 == 0) { + p_snprintf(buf, sizeof(buf), "icase/dir%02d/file", i); + cl_git_mkfile(buf, buf); + } + + for (j = 0; j < 10; ++j) { + p_snprintf(buf, sizeof(buf), "icase/dir%02d/sub%02d", i, j); + cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH)); + + if (j % 2 == 0) { + p_snprintf( + buf, sizeof(buf), "icase/dir%02d/sub%02d/file", i, j); + cl_git_mkfile(buf, buf); + } + } + } + + for (i = 1; i < 3; ++i) { + for (j = 0; j < 50; ++j) { + p_snprintf(buf, sizeof(buf), "icase/dir%02d/sub01/moar%02d", i, j); + cl_git_pass(git_futils_mkdir(buf, NULL, 0775, GIT_MKDIR_PATH)); + + if (j % 2 == 0) { + p_snprintf(buf, sizeof(buf), + "icase/dir%02d/sub01/moar%02d/file", i, j); + cl_git_mkfile(buf, buf); + } + } + } + + /* auto expand with no tree entries */ + cl_git_pass(git_iterator_for_workdir(&iter, g_repo, 0, NULL, NULL)); + expect_iterator_items(iter, 125, NULL, 125, NULL); + git_iterator_free(iter); + + /* auto expand with tree entries (empty dirs silently skipped) */ + cl_git_pass(git_iterator_for_workdir( + &iter, g_repo, GIT_ITERATOR_INCLUDE_TREES, NULL, NULL)); + expect_iterator_items(iter, 337, NULL, 337, NULL); + git_iterator_free(iter); +} |