diff options
author | Michael Schubert <schu@schu.io> | 2012-07-19 17:33:48 +0200 |
---|---|---|
committer | Michael Schubert <schu@schu.io> | 2012-07-19 18:44:08 +0200 |
commit | c6f429535c011160dc60547e5147695f2107a260 (patch) | |
tree | 934dd9674b3b1f9d21abb0b9c3d5ed0ebb13cc7d /src | |
parent | 5a8204f8a88c59c2cb07b93930834ef0a5aaf1fc (diff) | |
download | libgit2-c6f429535c011160dc60547e5147695f2107a260.tar.gz |
tree: fix ordering for git_tree_walk
Josh Triplett noticed libgit2 actually does preorder entries in
tree_walk_post instead of postorder. Also, we continued walking even
when an error occured in the callback.
Fix #773; also, allow both pre- and postorder walking.
Diffstat (limited to 'src')
-rw-r--r-- | src/tree.c | 20 |
1 files changed, 12 insertions, 8 deletions
@@ -759,11 +759,12 @@ int git_tree_entry_bypath( return error; } -static int tree_walk_post( +static int tree_walk( git_tree *tree, git_treewalk_cb callback, git_buf *path, - void *payload) + void *payload, + bool preorder) { int error = 0; unsigned int i; @@ -771,8 +772,8 @@ static int tree_walk_post( for (i = 0; i < tree->entries.length; ++i) { git_tree_entry *entry = tree->entries.contents[i]; - if (callback(path->ptr, entry, payload) < 0) - continue; + if (preorder && callback(path->ptr, entry, payload) < 0) + return -1; if (git_tree_entry__is_tree(entry)) { git_tree *subtree; @@ -789,12 +790,15 @@ static int tree_walk_post( if (git_buf_oom(path)) return -1; - if (tree_walk_post(subtree, callback, path, payload) < 0) + if (tree_walk(subtree, callback, path, payload, preorder) < 0) return -1; git_buf_truncate(path, path_len); git_tree_free(subtree); } + + if (!preorder && callback(path->ptr, entry, payload) < 0) + return -1; } return 0; @@ -807,12 +811,12 @@ int git_tree_walk(git_tree *tree, git_treewalk_cb callback, int mode, void *payl switch (mode) { case GIT_TREEWALK_POST: - error = tree_walk_post(tree, callback, &root_path, payload); + error = tree_walk(tree, callback, &root_path, payload, false); break; case GIT_TREEWALK_PRE: - tree_error("Preorder tree walking is still not implemented"); - return -1; + error = tree_walk(tree, callback, &root_path, payload, true); + break; default: giterr_set(GITERR_INVALID, "Invalid walking mode for tree walk"); |