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); }
emacs_value egit_tag_peel(emacs_env *env, emacs_value _tag) { EGIT_ASSERT_TAG(_tag); git_tag *tag = EGIT_EXTRACT(_tag); git_object *obj; int retval = git_tag_peel(&obj, tag); EGIT_CHECK_ERROR(retval); return egit_wrap(env, EGIT_OBJECT, obj, EGIT_EXTRACT_PARENT(_tag)); }
int git_branch_create( git_oid *oid_out, git_repository *repo, const char *branch_name, const git_object *target, int force) { git_otype target_type = GIT_OBJ_BAD; git_object *commit = NULL; git_reference *branch = NULL; git_buf canonical_branch_name = GIT_BUF_INIT; int error = -1; assert(repo && branch_name && target && oid_out); if (git_object_owner(target) != repo) return create_error_invalid("The given target does not belong to this repository"); target_type = git_object_type(target); switch (target_type) { case GIT_OBJ_TAG: if (git_tag_peel(&commit, (git_tag *)target) < 0) goto cleanup; if (git_object_type(commit) != GIT_OBJ_COMMIT) { create_error_invalid("The given target does not resolve to a commit"); goto cleanup; } break; case GIT_OBJ_COMMIT: commit = (git_object *)target; break; default: return create_error_invalid("Only git_tag and git_commit objects are valid targets."); } if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0) goto cleanup; if (git_reference_create_oid(&branch, repo, git_buf_cstr(&canonical_branch_name), git_object_id(commit), force) < 0) goto cleanup; git_oid_cpy(oid_out, git_reference_oid(branch)); error = 0; cleanup: if (target_type == GIT_OBJ_TAG) git_object_free(commit); git_reference_free(branch); git_buf_free(&canonical_branch_name); return error; }
static int mne_git_get_tag_commit_oid(const git_oid **tag_commit_oid, git_tag* tag) { git_object *tag_object; int err = git_tag_peel(&tag_object, tag); mne_check_error("git_tag_peel()", err, __FILE__, __LINE__); const git_otype type = git_object_type(tag_object); if (type != GIT_OBJ_COMMIT) return MNE_GIT_TARGET_NOT_COMMIT; *tag_commit_oid = git_object_id(tag_object); assert(tag_commit_oid != NULL); git_object_free(tag_object); return MNE_GIT_OK; }
int git_reset( git_repository *repo, const git_object *target, git_reset_type reset_type) { git_otype target_type = GIT_OBJ_BAD; git_object *commit = NULL; git_index *index = NULL; git_tree *tree = NULL; int error = -1; assert(repo && target); assert(reset_type == GIT_RESET_SOFT || reset_type == GIT_RESET_MIXED); if (git_object_owner(target) != repo) return reset_error_invalid("The given target does not belong to this repository."); if (reset_type == GIT_RESET_MIXED && git_repository_is_bare(repo)) return reset_error_invalid("Mixed reset is not allowed in a bare repository."); target_type = git_object_type(target); switch (target_type) { case GIT_OBJ_TAG: if (git_tag_peel(&commit, (git_tag *)target) < 0) goto cleanup; if (git_object_type(commit) != GIT_OBJ_COMMIT) { reset_error_invalid("The given target does not resolve to a commit."); goto cleanup; } break; case GIT_OBJ_COMMIT: commit = (git_object *)target; break; default: return reset_error_invalid("Only git_tag and git_commit objects are valid targets."); } //TODO: Check for unmerged entries if (git_reference__update(repo, git_object_id(commit), GIT_HEAD_FILE) < 0) goto cleanup; if (reset_type == GIT_RESET_SOFT) { error = 0; goto cleanup; } if (git_commit_tree(&tree, (git_commit *)commit) < 0) { giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the commit tree.", ERROR_MSG); goto cleanup; } if (git_repository_index(&index, repo) < 0) { giterr_set(GITERR_OBJECT, "%s - Failed to retrieve the index.", ERROR_MSG); goto cleanup; } if (git_index_read_tree(index, tree) < 0) { giterr_set(GITERR_INDEX, "%s - Failed to update the index.", ERROR_MSG); goto cleanup; } if (git_index_write(index) < 0) { giterr_set(GITERR_INDEX, "%s - Failed to write the index.", ERROR_MSG); goto cleanup; } error = 0; cleanup: if (target_type == GIT_OBJ_TAG) git_object_free(commit); git_index_free(index); git_tree_free(tree); return error; }
static int add_ref(transport_local *t, const char *name) { const char peeled[] = "^{}"; git_remote_head *head; git_object *obj = NULL, *target = NULL; git_transport *transport = (git_transport *) t; git_buf buf = GIT_BUF_INIT; git_pkt_ref *pkt; head = git__malloc(sizeof(git_remote_head)); GITERR_CHECK_ALLOC(head); pkt = git__malloc(sizeof(git_pkt_ref)); GITERR_CHECK_ALLOC(pkt); head->name = git__strdup(name); GITERR_CHECK_ALLOC(head->name); if (git_reference_name_to_oid(&head->oid, t->repo, name) < 0) { git__free(head); git__free(pkt->head.name); git__free(pkt); } pkt->type = GIT_PKT_REF; memcpy(&pkt->head, head, sizeof(git_remote_head)); git__free(head); if (git_vector_insert(&transport->refs, pkt) < 0) { git__free(pkt->head.name); git__free(pkt); return -1; } /* If it's not a tag, we don't need to try to peel it */ if (git__prefixcmp(name, GIT_REFS_TAGS_DIR)) return 0; if (git_object_lookup(&obj, t->repo, &pkt->head.oid, GIT_OBJ_ANY) < 0) return -1; head = NULL; /* If it's not an annotated tag, just get out */ if (git_object_type(obj) != GIT_OBJ_TAG) { git_object_free(obj); return 0; } /* And if it's a tag, peel it, and add it to the list */ head = git__malloc(sizeof(git_remote_head)); GITERR_CHECK_ALLOC(head); if (git_buf_join(&buf, 0, name, peeled) < 0) return -1; head->name = git_buf_detach(&buf); pkt = git__malloc(sizeof(git_pkt_ref)); GITERR_CHECK_ALLOC(pkt); pkt->type = GIT_PKT_REF; if (git_tag_peel(&target, (git_tag *) obj) < 0) goto on_error; git_oid_cpy(&head->oid, git_object_id(target)); git_object_free(obj); git_object_free(target); memcpy(&pkt->head, head, sizeof(git_remote_head)); git__free(head); if (git_vector_insert(&transport->refs, pkt) < 0) return -1; return 0; on_error: git_object_free(obj); git_object_free(target); return -1; }