static int find_subtree_r(git_tree **out, git_tree *root, git_repository *repo, const char *target, int *fanout) { int error; git_tree *subtree = NULL; *out = NULL; error = find_subtree_in_current_level(&subtree, repo, root, target, *fanout); if (error == GIT_EEXISTS) return git_tree_lookup(out, repo, git_tree_id(root)); if (error < 0) return error; *fanout += 2; error = find_subtree_r(out, subtree, repo, target, fanout); git_tree_free(subtree); return error; }
static int manipulate_note_in_tree_r( git_tree **out, git_repository *repo, git_tree *parent, git_oid *note_oid, const char *annotated_object_sha, int fanout, int (*note_exists_cb)( git_tree **out, git_repository *repo, git_tree *parent, git_oid *note_oid, const char *annotated_object_sha, int fanout, int current_error), int (*note_notfound_cb)( git_tree **out, git_repository *repo, git_tree *parent, git_oid *note_oid, const char *annotated_object_sha, int fanout, int current_error)) { int error = -1; git_tree *subtree = NULL, *new = NULL; char subtree_name[3]; error = find_subtree_in_current_level( &subtree, repo, parent, annotated_object_sha, fanout); if (error == GIT_EEXISTS) { error = note_exists_cb( out, repo, parent, note_oid, annotated_object_sha, fanout, error); goto cleanup; } if (error == GIT_ENOTFOUND) { error = note_notfound_cb( out, repo, parent, note_oid, annotated_object_sha, fanout, error); goto cleanup; } if (error < 0) goto cleanup; /* An existing fanout has been found, let's dig deeper */ error = manipulate_note_in_tree_r( &new, repo, subtree, note_oid, annotated_object_sha, fanout + 2, note_exists_cb, note_notfound_cb); if (error < 0) goto cleanup; strncpy(subtree_name, annotated_object_sha + fanout, 2); subtree_name[2] = '\0'; error = tree_write(out, repo, parent, git_tree_id(new), subtree_name, GIT_FILEMODE_TREE); cleanup: git_tree_free(new); git_tree_free(subtree); return error; }