diff options
author | Daniel Ferreira <bnmvco@gmail.com> | 2017-04-26 10:03:39 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-05-29 14:40:55 +0900 |
commit | b82295107a3089eb4ef605ee05c17b266aef91bc (patch) | |
tree | f9d28ee45368b5137807409eef609a3b29b636ad | |
parent | 019440b2f039154c6a6da17088da206dd7e384ed (diff) | |
download | git-df/dir-iter-remove-subtree.tar.gz |
remove_subtree(): reimplement using iteratorsdf/dir-iter-remove-subtree
Use dir_iterator to traverse through remove_subtree()'s directory tree,
avoiding the need for recursive calls to readdir(). Simplify
remove_subtree()'s code.
A conversion similar in purpose was previously done at 46d092a
("for_each_reflog(): reimplement using iterators", 2016-05-21).
Signed-off-by: Daniel Ferreira <bnmvco@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | entry.c | 42 |
1 files changed, 16 insertions, 26 deletions
@@ -3,6 +3,8 @@ #include "dir.h" #include "streaming.h" #include "submodule.h" +#include "iterator.h" +#include "dir-iterator.h" static void create_directories(const char *path, int path_len, const struct checkout *state) @@ -45,33 +47,21 @@ static void create_directories(const char *path, int path_len, free(buf); } -static void remove_subtree(struct strbuf *path) +static void remove_subtree(const char *path) { - DIR *dir = opendir(path->buf); - struct dirent *de; - int origlen = path->len; - - if (!dir) - die_errno("cannot opendir '%s'", path->buf); - while ((de = readdir(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)) - die_errno("cannot lstat '%s'", path->buf); - if (S_ISDIR(st.st_mode)) - remove_subtree(path); - else if (unlink(path->buf)) - die_errno("cannot unlink '%s'", path->buf); - strbuf_setlen(path, origlen); + struct dir_iterator *diter = dir_iterator_begin(path, + DIR_ITERATOR_POST_ORDER_TRAVERSAL | DIR_ITERATOR_LIST_ROOT_DIR); + if (!diter) { + die_errno("cannot remove path '%s'", path); + } + + while (dir_iterator_advance(diter) == ITER_OK) { + if (S_ISDIR(diter->st.st_mode)) { + if (rmdir(diter->path.buf)) + die_errno("cannot rmdir '%s'", diter->path.buf); + } else if (unlink(diter->path.buf)) + die_errno("cannot unlink '%s'", diter->path.buf); } - closedir(dir); - if (rmdir(path->buf)) - die_errno("cannot rmdir '%s'", path->buf); } static int create_file(const char *path, unsigned int mode) @@ -312,7 +302,7 @@ int checkout_entry(struct cache_entry *ce, return 0; if (!state->force) return error("%s is a directory", path.buf); - remove_subtree(&path); + remove_subtree(path.buf); } else if (unlink(path.buf)) return error_errno("unable to unlink old '%s'", path.buf); } else if (state->not_new) |