static int dereference_to_non_tag(git_object **out, git_object *obj) { if (git_object_type(obj) == GIT_OBJ_TAG) return git_tag_peel(out, (git_tag *)obj); return git_object__dup(out, obj); }
int git_object_peel( git_object **peeled, const git_object *object, git_otype target_type) { git_object *source, *deref = NULL; int error; if (target_type != GIT_OBJ_TAG && target_type != GIT_OBJ_COMMIT && target_type != GIT_OBJ_TREE && target_type != GIT_OBJ_BLOB && target_type != GIT_OBJ_ANY) return GIT_EINVALIDSPEC; assert(object && peeled); if (git_object_type(object) == target_type) return git_object__dup(peeled, (git_object *)object); source = (git_object *)object; while (!(error = dereference_object(&deref, source))) { if (source != object) git_object_free(source); if (git_object_type(deref) == target_type) { *peeled = deref; return 0; } if (target_type == GIT_OBJ_ANY && git_object_type(deref) != git_object_type(object)) { *peeled = deref; return 0; } source = deref; deref = NULL; } if (source != object) git_object_free(source); git_object_free(deref); if (error) error = peel_error(error, git_object_id(object), target_type); return error; }