path: root/refs/files-backend.c
diff options
authorMatheus Tavares <>2019-07-10 23:58:59 (GMT)
committerJunio C Hamano <>2019-07-11 20:52:15 (GMT)
commit3012397e0327f5e4dfd1d1183a792268429744ae (patch)
tree79faf55ec5f3ce158864c809e309cc3fa5a0da17 /refs/files-backend.c
parentc9bba372ed9ee0c5ea1a4037c3c723a6c31f5921 (diff)
dir-iterator: refactor state machine model
dir_iterator_advance() is a large function with two nested loops. Let's improve its readability factoring out three functions and simplifying its mechanics. The refactored model will no longer depend on level.initialized and level.dir_state to keep track of the iteration state and will perform on a single loop. Also, dir_iterator_begin() currently does not check if the given string represents a valid directory path. Since the refactored model will have to stat() the given path at initialization, let's also check for this kind of error and make dir_iterator_begin() return NULL, on failures, with errno appropriately set. And add tests for this new behavior. Improve documentation at dir-iteration.h and code comments at dir-iterator.c to reflect the changes and eliminate possible ambiguities. Finally, adjust refs/files-backend.c to check for now possible dir_iterator_begin() failures. Original-patch-by: Daniel Ferreira <> Signed-off-by: Matheus Tavares <> Signed-off-by: Junio C Hamano <>
Diffstat (limited to 'refs/files-backend.c')
1 files changed, 13 insertions, 4 deletions
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 63e55e6..7ed8104 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2143,13 +2143,22 @@ static struct ref_iterator_vtable files_reflog_iterator_vtable = {
static struct ref_iterator *reflog_iterator_begin(struct ref_store *ref_store,
const char *gitdir)
- struct files_reflog_iterator *iter = xcalloc(1, sizeof(*iter));
- struct ref_iterator *ref_iterator = &iter->base;
+ struct dir_iterator *diter;
+ struct files_reflog_iterator *iter;
+ struct ref_iterator *ref_iterator;
struct strbuf sb = STRBUF_INIT;
- base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 0);
strbuf_addf(&sb, "%s/logs", gitdir);
- iter->dir_iterator = dir_iterator_begin(sb.buf);
+ diter = dir_iterator_begin(sb.buf);
+ if(!diter)
+ return empty_ref_iterator_begin();
+ iter = xcalloc(1, sizeof(*iter));
+ ref_iterator = &iter->base;
+ base_ref_iterator_init(ref_iterator, &files_reflog_iterator_vtable, 0);
+ iter->dir_iterator = diter;
iter->ref_store = ref_store;