summaryrefslogtreecommitdiff
path: root/src/tree.c
diff options
context:
space:
mode:
authornulltoken <emeric.fermas@gmail.com>2011-10-13 23:17:19 +0200
committernulltoken <emeric.fermas@gmail.com>2011-10-13 23:30:07 +0200
commit3fa735ca3b8d8f855e43be44b5f96e59909d50e1 (patch)
tree920698d515abc6a21adf3676b3694f52be80bb5a /src/tree.c
parent34aff0100248dbf349240fd8edff4cc440062b40 (diff)
downloadlibgit2-3fa735ca3b8d8f855e43be44b5f96e59909d50e1.tar.gz
tree: Add git_tree_frompath() which, given a relative path to a tree entry, retrieves the tree object containing this tree entry
Diffstat (limited to 'src/tree.c')
-rw-r--r--src/tree.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/tree.c b/src/tree.c
index 0acf74ede..3801df1dd 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -559,4 +559,49 @@ void git_treebuilder_free(git_treebuilder *bld)
free(bld);
}
+static int tree_frompath(git_tree **parent_out, git_tree *root, const char *treeentry_path, int offset)
+{
+ char *slash_pos = NULL;
+ const git_tree_entry* entry;
+ int error = GIT_SUCCESS;
+ git_tree *subtree;
+
+ if (!*(treeentry_path + offset))
+ return git__rethrow(GIT_EINVALIDPATH, "Invalid relative path to a tree entry '%s'.", treeentry_path);
+
+ slash_pos = (char *)strchr(treeentry_path + offset, '/');
+
+ if (slash_pos == NULL)
+ return git_tree_lookup(parent_out, root->object.repo, git_object_id((const git_object *)root));
+
+ if (slash_pos == treeentry_path + offset)
+ return git__rethrow(GIT_EINVALIDPATH, "Invalid relative path to a tree entry '%s'.", treeentry_path);
+
+ *slash_pos = '\0';
+
+ entry = git_tree_entry_byname(root, treeentry_path + offset);
+
+ if (slash_pos != NULL)
+ *slash_pos = '/';
+
+ if (entry == NULL)
+ return git__rethrow(GIT_ENOTFOUND, "No tree entry can be found from the given tree and relative path '%s'.", treeentry_path);
+ if ((error = git_tree_lookup(&subtree, root->object.repo, &entry->oid)) < GIT_SUCCESS)
+ return error;
+
+ error = tree_frompath(parent_out, subtree, treeentry_path, slash_pos - treeentry_path + 1);
+
+ git_tree_close(subtree);
+ return error;
+}
+
+int git_tree_frompath(git_tree **parent_out, git_tree *root, const char *treeentry_path)
+{
+ char buffer[GIT_PATH_MAX];
+
+ assert(root && treeentry_path);
+
+ strcpy(buffer, treeentry_path);
+ return tree_frompath(parent_out, root, buffer, 0);
+}