void test_refs_overwrite__object_id(void) { // Overwrite an existing object id reference git_reference *ref; git_oid id; cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name)); cl_assert(git_reference_type(ref) & GIT_REF_OID); git_oid_cpy(&id, git_reference_target(ref)); git_reference_free(ref); /* Create it */ cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 0)); git_reference_free(ref); cl_git_pass(git_reference_lookup(&ref, g_repo, ref_test_name)); cl_assert(git_reference_type(ref) & GIT_REF_OID); git_oid_cpy(&id, git_reference_target(ref)); git_reference_free(ref); /* Ensure we can't overwrite unless we force it */ cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0)); cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1)); git_reference_free(ref); /* Ensure it has been overwritten */ cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name)); cl_assert(!git_oid_cmp(&id, git_reference_target(ref))); git_reference_free(ref); }
void test_refs_overwrite__symbolic_with_object_id(void) { // Overwrite an existing symbolic reference with an object id one git_reference *ref; git_oid id; cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name)); cl_assert(git_reference_type(ref) & GIT_REF_OID); git_oid_cpy(&id, git_reference_target(ref)); git_reference_free(ref); /* Create the symbolic ref */ cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); git_reference_free(ref); /* It shouldn't overwrite unless we tell it to */ cl_git_fail(git_reference_create(&ref, g_repo, ref_name, &id, 0)); cl_git_pass(git_reference_create(&ref, g_repo, ref_name, &id, 1)); git_reference_free(ref); /* Ensure it points to the right place */ cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name)); cl_assert(git_reference_type(ref) & GIT_REF_OID); cl_assert(!git_oid_cmp(git_reference_target(ref), &id)); git_reference_free(ref); }
void test_refs_read__nested_symbolic(void) { // lookup a nested symbolic reference git_reference *reference, *resolved_ref; git_object *object; git_oid id; cl_git_pass(git_reference_lookup(&reference, g_repo, head_tracker_sym_ref_name)); cl_assert(git_reference_type(reference) & GIT_REF_SYMBOLIC); cl_assert(git_reference_is_packed(reference) == 0); cl_assert_equal_s(reference->name, head_tracker_sym_ref_name); cl_git_pass(git_reference_resolve(&resolved_ref, reference)); cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID); cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(resolved_ref), GIT_OBJ_ANY)); cl_assert(object != NULL); cl_assert(git_object_type(object) == GIT_OBJ_COMMIT); git_oid_fromstr(&id, current_master_tip); cl_assert(git_oid_cmp(&id, git_object_id(object)) == 0); git_object_free(object); git_reference_free(reference); git_reference_free(resolved_ref); }
void test_refs_overwrite__symbolic(void) { // Overwrite an existing symbolic reference git_reference *ref, *branch_ref; /* The target needds to exist and we need to check the name has changed */ cl_git_pass(git_reference_symbolic_create(&branch_ref, g_repo, ref_branch_name, ref_master_name, 0)); cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_branch_name, 0)); git_reference_free(ref); /* Ensure it points to the right place*/ cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name)); cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC); cl_assert_equal_s(git_reference_symbolic_target(ref), ref_branch_name); git_reference_free(ref); /* Ensure we can't create it unless we force it to */ cl_git_fail(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 0)); cl_git_pass(git_reference_symbolic_create(&ref, g_repo, ref_name, ref_master_name, 1)); git_reference_free(ref); /* Ensure it points to the right place */ cl_git_pass(git_reference_lookup(&ref, g_repo, ref_name)); cl_assert(git_reference_type(ref) & GIT_REF_SYMBOLIC); cl_assert_equal_s(git_reference_symbolic_target(ref), ref_master_name); git_reference_free(ref); git_reference_free(branch_ref); }
int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_t branch_type) { git_reference *branch = NULL; git_reference *head = NULL; int error; assert((branch_type == GIT_BRANCH_LOCAL) || (branch_type == GIT_BRANCH_REMOTE)); if ((error = retrieve_branch_reference(&branch, repo, branch_name, branch_type == GIT_BRANCH_REMOTE)) < 0) return error; if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) { giterr_set(GITERR_REFERENCE, "Cannot locate HEAD."); goto on_error; } if ((git_reference_type(head) == GIT_REF_SYMBOLIC) && (strcmp(git_reference_target(head), git_reference_name(branch)) == 0)) { giterr_set(GITERR_REFERENCE, "Cannot delete branch '%s' as it is the current HEAD of the repository.", branch_name); goto on_error; } if (git_reference_delete(branch) < 0) goto on_error; git_reference_free(head); return 0; on_error: git_reference_free(head); git_reference_free(branch); return -1; }
void test_online_clone__clone_mirror(void) { git_buf path = GIT_BUF_INIT; git_remote *remote; git_reference *head; git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; bool fetch_progress_cb_was_called = false; cl_git_pass(git_repository_init(&g_repo, "./foo.git", true)); cl_git_pass(git_remote_create(&remote, g_repo, "origin", LIVE_REPO_URL)); callbacks.transfer_progress = &fetch_progress; callbacks.payload = &fetch_progress_cb_was_called; git_remote_set_callbacks(remote, &callbacks); git_remote_clear_refspecs(remote); cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*")); cl_git_pass(git_clone_into(g_repo, remote, NULL, NULL, NULL)); cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); cl_assert_equal_i(true, fetch_progress_cb_was_called); git_remote_free(remote); git_reference_free(head); git_buf_free(&path); git_repository_free(g_repo); g_repo = NULL; cl_fixture_cleanup("./foo.git"); }
static int update_wt_heads(git_repository *repo, const char *path, void *payload) { rename_cb_data *data = (rename_cb_data *) payload; git_reference *head = NULL; char *gitdir = NULL; int error; if ((error = git_reference__read_head(&head, repo, path)) < 0) { giterr_set(GITERR_REFERENCE, "could not read HEAD when renaming references"); goto out; } if ((gitdir = git_path_dirname(path)) == NULL) { error = -1; goto out; } if (git_reference_type(head) != GIT_REF_SYMBOLIC || git__strcmp(head->target.symbolic, data->old_name) != 0) { error = 0; goto out; } /* Update HEAD it was pointing to the reference being renamed */ if ((error = git_repository_create_head(gitdir, data->new_name)) < 0) { giterr_set(GITERR_REFERENCE, "failed to update HEAD after renaming reference"); goto out; } out: git_reference_free(head); git__free(gitdir); return error; }
/** * ggit_ref_get_reference_type: * @ref: a #GgitRef. * * Gets the type of @ref. Either direct (#GGIT_REF_OID) or * symbolic (#GGIT_REF_SYMBOLIC). * * Returns: the type of a reference. */ GgitRefType ggit_ref_get_reference_type (GgitRef *ref) { g_return_val_if_fail (ref != NULL, GGIT_REF_INVALID); return (GgitRefType)git_reference_type (_ggit_native_get (ref)); }
/* * call-seq: * ref.peel -> oid * * Peels tag objects to the sha that they point at. Replicates * +git show-ref --dereference+. */ static VALUE rb_git_ref_peel(VALUE self) { /* Leave room for \0 */ git_reference *ref; git_object *object; char oid[GIT_OID_HEXSZ + 1]; int error; Data_Get_Struct(self, git_reference, ref); error = git_reference_peel(&object, ref, GIT_OBJ_ANY); if (error == GIT_ENOTFOUND) return Qnil; else rugged_exception_check(error); if (git_reference_type(ref) == GIT_REF_OID && !git_oid_cmp(git_object_id(object), git_reference_target(ref))) { git_object_free(object); return Qnil; } else { git_oid_tostr(oid, sizeof(oid), git_object_id(object)); git_object_free(object); return rb_str_new_utf8(oid); } }
static int show_ref(git_reference *ref, void *data) { git_repository *repo = data; git_reference *resolved = NULL; char hex[GIT_OID_HEXSZ+1]; const git_oid *oid; git_object *obj; if (git_reference_type(ref) == GIT_REF_SYMBOLIC) check_lg2(git_reference_resolve(&resolved, ref), "Unable to resolve symbolic reference", git_reference_name(ref)); oid = git_reference_target(resolved ? resolved : ref); git_oid_fmt(hex, oid); hex[GIT_OID_HEXSZ] = 0; check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJ_ANY), "Unable to lookup object", hex); printf("%s %-6s\t%s\n", hex, git_object_type2string(git_object_type(obj)), git_reference_name(ref)); if (resolved) git_reference_free(resolved); return 0; }
int git_repository_is_empty(git_repository *repo) { git_reference *head = NULL, *branch = NULL; int error; if (git_reference_lookup(&head, repo, "HEAD") < 0) return -1; if (git_reference_type(head) != GIT_REF_SYMBOLIC) { git_reference_free(head); return 0; } if (strcmp(git_reference_target(head), "refs/heads/master") != 0) { git_reference_free(head); return 0; } error = git_reference_resolve(&branch, head); git_reference_free(head); git_reference_free(branch); if (error == GIT_ENOTFOUND) return 1; if (error < 0) return -1; return 0; }
void test_network_fetchlocal__clone_into_mirror(void) { git_buf path = GIT_BUF_INIT; git_repository *repo; git_remote *remote; git_reference *head; cl_git_pass(git_repository_init(&repo, "./foo.git", true)); cl_git_pass(git_remote_create(&remote, repo, "origin", cl_git_fixture_url("testrepo.git"))); git_remote_clear_refspecs(remote); cl_git_pass(git_remote_add_fetch(remote, "+refs/*:refs/*")); cl_git_pass(git_clone_into(repo, remote, NULL, NULL, NULL)); cl_git_pass(git_reference_lookup(&head, repo, "HEAD")); cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); git_remote_free(remote); git_reference_free(head); git_repository_free(repo); git_buf_free(&path); cl_fixture_cleanup("./foo.git"); }
void test_refs_read__loose_tag(void) { // lookup a loose tag reference git_reference *reference; git_object *object; git_buf ref_name_from_tag_name = GIT_BUF_INIT; cl_git_pass(git_reference_lookup(&reference, g_repo, loose_tag_ref_name)); cl_assert(git_reference_type(reference) & GIT_REF_OID); cl_assert(git_reference_is_packed(reference) == 0); cl_assert_equal_s(reference->name, loose_tag_ref_name); cl_git_pass(git_object_lookup(&object, g_repo, git_reference_target(reference), GIT_OBJ_ANY)); cl_assert(object != NULL); cl_assert(git_object_type(object) == GIT_OBJ_TAG); /* Ensure the name of the tag matches the name of the reference */ cl_git_pass(git_buf_joinpath(&ref_name_from_tag_name, GIT_REFS_TAGS_DIR, git_tag_name((git_tag *)object))); cl_assert_equal_s(ref_name_from_tag_name.ptr, loose_tag_ref_name); git_buf_free(&ref_name_from_tag_name); git_object_free(object); git_reference_free(reference); }
void test_refs_create__oid(void) { /* create a new OID reference */ git_reference *new_reference, *looked_up_ref; git_repository *repo2; git_oid id; const char *new_head = "refs/heads/new-head"; git_oid_fromstr(&id, current_master_tip); /* Create and write the new object id reference */ cl_git_pass(git_reference_create(&new_reference, g_repo, new_head, &id, 0, NULL)); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head)); cl_assert(git_reference_type(looked_up_ref) & GIT_REF_OID); cl_assert(reference_is_packed(looked_up_ref) == 0); cl_assert_equal_s(looked_up_ref->name, new_head); /* ...and that it points to the current master tip */ cl_assert_equal_oid(&id, git_reference_target(looked_up_ref)); git_reference_free(looked_up_ref); /* Similar test with a fresh new repository */ cl_git_pass(git_repository_open(&repo2, "testrepo")); cl_git_pass(git_reference_lookup(&looked_up_ref, repo2, new_head)); cl_assert_equal_oid(&id, git_reference_target(looked_up_ref)); git_repository_free(repo2); git_reference_free(new_reference); git_reference_free(looked_up_ref); }
void test_online_clone__can_checkout_a_cloned_repo(void) { git_buf path = GIT_BUF_INIT; git_reference *head; bool checkout_progress_cb_was_called = false, fetch_progress_cb_was_called = false; g_options.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; g_options.checkout_opts.progress_cb = &checkout_progress; g_options.checkout_opts.progress_payload = &checkout_progress_cb_was_called; g_options.fetch_opts.callbacks.transfer_progress = &fetch_progress; g_options.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called; cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo", &g_options)); cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "master.txt")); cl_assert_equal_i(true, git_path_isfile(git_buf_cstr(&path))); cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); cl_assert_equal_i(true, checkout_progress_cb_was_called); cl_assert_equal_i(true, fetch_progress_cb_was_called); git_reference_free(head); git_buf_free(&path); }
const git_oid *lookup_master_tree(git_repository *repo) { int ret; git_reference *ref; const git_oid *commit_oid; const git_oid *tree_oid; git_commit *commit; ret = git_reference_lookup(&ref, repo, "refs/heads/master"); if (ret) { printf("git_reference_lookup() error: %s\n", git_strerror(ret)); return NULL; } if (git_reference_type(ref) != GIT_REF_OID) { perror("reference_type is not oid reference."); return NULL; } commit_oid = git_reference_oid(ref); ret = git_commit_lookup(&commit, repo, commit_oid); tree_oid = git_commit_tree_oid(commit); git_commit_free(commit); return tree_oid; }
/** * Get the end of a chain of references. If the final one is not * found, we return the reference just before that. */ static int get_terminal(git_reference **out, git_repository *repo, const char *ref_name, int nesting) { git_reference *ref; int error = 0; if (nesting > MAX_NESTING_LEVEL) { giterr_set(GITERR_REFERENCE, "Reference chain too deep (%d)", nesting); return GIT_ENOTFOUND; } /* set to NULL to let the caller know that they're at the end of the chain */ if ((error = git_reference_lookup(&ref, repo, ref_name)) < 0) { *out = NULL; return error; } if (git_reference_type(ref) == GIT_REF_OID) { *out = ref; error = 0; } else { error = get_terminal(out, repo, git_reference_symbolic_target(ref), nesting + 1); if (error == GIT_ENOTFOUND && !*out) *out = ref; else git_reference_free(ref); } return error; }
void test_refs_rename__prefix(void) { // can be renamed to a new name prefixed with the old name git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref; git_oid id; cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name)); cl_assert(git_reference_type(ref) & GIT_REF_OID); git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL)); /* An existing reference... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name)); /* Can be rename to a new name starting with the old name. */ cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name_new, 0, NULL)); git_reference_free(looked_up_ref); git_reference_free(renamed_ref); /* Check we actually renamed it */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new)); cl_assert_equal_s(looked_up_ref->name, ref_two_name_new); git_reference_free(looked_up_ref); cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name)); git_reference_free(ref); git_reference_free(ref_two); git_reference_free(looked_up_ref); }
void test_refs_rename__move_up(void) { // can move a reference to a upper reference hierarchy git_reference *ref, *ref_two, *looked_up_ref, *renamed_ref; git_oid id; cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name)); cl_assert(git_reference_type(ref) & GIT_REF_OID); git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name_new, &id, 0, NULL)); git_reference_free(ref_two); /* An existing reference... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new)); /* Can be renamed upward the reference tree. */ cl_git_pass(git_reference_rename(&renamed_ref, looked_up_ref, ref_two_name, 0, NULL)); git_reference_free(looked_up_ref); git_reference_free(renamed_ref); /* Check we actually renamed it */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name)); cl_assert_equal_s(looked_up_ref->name, ref_two_name); git_reference_free(looked_up_ref); cl_git_fail(git_reference_lookup(&looked_up_ref, g_repo, ref_two_name_new)); git_reference_free(ref); git_reference_free(looked_up_ref); }
void test_refs_rename__overwrite(void) { // can not overwrite name of existing reference git_reference *ref, *ref_one, *ref_one_new, *ref_two; git_refdb *refdb; git_oid id; cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name)); cl_assert(git_reference_type(ref) & GIT_REF_OID); git_oid_cpy(&id, git_reference_target(ref)); /* Create loose references */ cl_git_pass(git_reference_create(&ref_one, g_repo, ref_one_name, &id, 0, NULL)); cl_git_pass(git_reference_create(&ref_two, g_repo, ref_two_name, &id, 0, NULL)); /* Pack everything */ cl_git_pass(git_repository_refdb(&refdb, g_repo)); cl_git_pass(git_refdb_compress(refdb)); /* Attempt to create illegal reference */ cl_git_fail(git_reference_create(&ref_one_new, g_repo, ref_one_name_new, &id, 0, NULL)); /* Illegal reference couldn't be created so this is supposed to fail */ cl_git_fail(git_reference_lookup(&ref_one_new, g_repo, ref_one_name_new)); git_reference_free(ref); git_reference_free(ref_one); git_reference_free(ref_one_new); git_reference_free(ref_two); git_refdb_free(refdb); }
void test_online_clone__clone_mirror(void) { git_clone_options opts = GIT_CLONE_OPTIONS_INIT; git_reference *head; bool fetch_progress_cb_was_called = false; opts.fetch_opts.callbacks.transfer_progress = &fetch_progress; opts.fetch_opts.callbacks.payload = &fetch_progress_cb_was_called; opts.bare = true; opts.remote_cb = remote_mirror_cb; cl_git_pass(git_clone(&g_repo, LIVE_REPO_URL, "./foo.git", &opts)); cl_git_pass(git_reference_lookup(&head, g_repo, "HEAD")); cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head)); cl_assert_equal_s("refs/heads/master", git_reference_symbolic_target(head)); cl_assert_equal_i(true, fetch_progress_cb_was_called); git_reference_free(head); git_repository_free(g_repo); g_repo = NULL; cl_fixture_cleanup("./foo.git"); }
void test_refs_create__symbolic_with_arbitrary_content(void) { git_reference *new_reference, *looked_up_ref; git_repository *repo2; git_oid id; const char *new_head_tracker = "ANOTHER_HEAD_TRACKER"; const char *arbitrary_target = "ARBITRARY DATA"; git_oid_fromstr(&id, current_master_tip); /* Attempt to create symbolic ref with arbitrary data in target * fails by default */ cl_git_fail(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, arbitrary_target, 0, NULL)); git_libgit2_opts(GIT_OPT_ENABLE_STRICT_SYMBOLIC_REF_CREATION, 0); /* With strict target validation disabled, ref creation succeeds */ cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, arbitrary_target, 0, NULL)); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker)); cl_assert(git_reference_type(looked_up_ref) & GIT_REF_SYMBOLIC); cl_assert(reference_is_packed(looked_up_ref) == 0); cl_assert_equal_s(looked_up_ref->name, new_head_tracker); git_reference_free(looked_up_ref); /* Ensure the target is what we expect it to be */ cl_assert_equal_s(git_reference_symbolic_target(new_reference), arbitrary_target); /* Similar test with a fresh new repository object */ cl_git_pass(git_repository_open(&repo2, "testrepo")); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, repo2, new_head_tracker)); cl_assert(git_reference_type(looked_up_ref) & GIT_REF_SYMBOLIC); cl_assert(reference_is_packed(looked_up_ref) == 0); cl_assert_equal_s(looked_up_ref->name, new_head_tracker); /* Ensure the target is what we expect it to be */ cl_assert_equal_s(git_reference_symbolic_target(new_reference), arbitrary_target); git_repository_free(repo2); git_reference_free(new_reference); git_reference_free(looked_up_ref); }
void test_rebase_merge__finish(void) { git_rebase *rebase; git_reference *branch_ref, *upstream_ref, *head_ref; git_annotated_commit *branch_head, *upstream_head; git_rebase_operation *rebase_operation; git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT; git_oid commit_id; git_reflog *reflog; const git_reflog_entry *reflog_entry; int error; checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE; cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/gravy")); cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/veal")); cl_git_pass(git_annotated_commit_from_ref(&branch_head, repo, branch_ref)); cl_git_pass(git_annotated_commit_from_ref(&upstream_head, repo, upstream_ref)); cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL)); cl_git_pass(git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature, NULL, NULL)); cl_git_fail(error = git_rebase_next(&rebase_operation, rebase, &checkout_opts)); cl_assert_equal_i(GIT_ITEROVER, error); cl_git_pass(git_rebase_finish(rebase, signature, NULL)); cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo)); cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD")); cl_assert_equal_i(GIT_REF_SYMBOLIC, git_reference_type(head_ref)); cl_assert_equal_s("refs/heads/gravy", git_reference_symbolic_target(head_ref)); /* Make sure the reflogs are updated appropriately */ cl_git_pass(git_reflog_read(&reflog, repo, "HEAD")); cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0)); cl_assert_equal_oid(&commit_id, git_reflog_entry_id_old(reflog_entry)); cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry)); cl_assert_equal_s("rebase finished: returning to refs/heads/gravy", git_reflog_entry_message(reflog_entry)); git_reflog_free(reflog); cl_git_pass(git_reflog_read(&reflog, repo, "refs/heads/gravy")); cl_assert(reflog_entry = git_reflog_entry_byindex(reflog, 0)); cl_assert_equal_oid(git_annotated_commit_id(branch_head), git_reflog_entry_id_old(reflog_entry)); cl_assert_equal_oid(&commit_id, git_reflog_entry_id_new(reflog_entry)); cl_assert_equal_s("rebase finished: refs/heads/gravy onto f87d14a4a236582a0278a916340a793714256864", git_reflog_entry_message(reflog_entry)); git_reflog_free(reflog); git_annotated_commit_free(branch_head); git_annotated_commit_free(upstream_head); git_reference_free(head_ref); git_reference_free(branch_ref); git_reference_free(upstream_ref); git_rebase_free(rebase); }
int git_reference_cmp(git_reference *ref1, git_reference *ref2) { git_ref_t type1, type2; assert(ref1 && ref2); type1 = git_reference_type(ref1); type2 = git_reference_type(ref2); /* let's put symbolic refs before OIDs */ if (type1 != type2) return (type1 == GIT_REF_SYMBOLIC) ? -1 : 1; if (type1 == GIT_REF_SYMBOLIC) return strcmp(ref1->target.symbolic, ref2->target.symbolic); return git_oid__cmp(&ref1->target.oid, &ref2->target.oid); }
PyObject * Reference_type__get__(Reference *self) { git_ref_t c_type; CHECK_REFERENCE(self); c_type = git_reference_type(self->reference); return PyLong_FromLong(c_type); }
PyObject * Reference_set_target(Reference *self, PyObject *args, PyObject *kwds) { git_oid oid; char *c_name; int err; git_reference *new_ref; const git_signature *sig = NULL; PyObject *py_target = NULL; Signature *py_signature = NULL; const char *message = NULL; char *keywords[] = {"target", "signature", "message", NULL}; CHECK_REFERENCE(self); if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O!s", keywords, &py_target, &SignatureType, &py_signature, &message)) return NULL; if (py_signature) sig = py_signature->signature; /* Case 1: Direct */ if (GIT_REF_OID == git_reference_type(self->reference)) { err = py_oid_to_git_oid_expand(self->repo->repo, py_target, &oid); if (err < 0) goto error; err = git_reference_set_target(&new_ref, self->reference, &oid, sig, message); if (err < 0) goto error; git_reference_free(self->reference); self->reference = new_ref; Py_RETURN_NONE; } /* Case 2: Symbolic */ c_name = py_path_to_c_str(py_target); if (c_name == NULL) return NULL; err = git_reference_symbolic_set_target(&new_ref, self->reference, c_name, sig, message); free(c_name); if (err < 0) goto error; git_reference_free(self->reference); self->reference = new_ref; Py_RETURN_NONE; error: Error_set(err); return NULL; }
void test_refs_update__updating_the_target_of_a_symref_with_an_invalid_name_returns_EINVALIDSPEC(void) { git_reference *head; cl_git_pass(git_reference_lookup(&head, g_repo, GIT_HEAD_FILE)); cl_assert_equal_i(GIT_REFERENCE_SYMBOLIC, git_reference_type(head)); git_reference_free(head); cl_assert_equal_i(GIT_EINVALIDSPEC, git_reference_symbolic_create(&head, g_repo, GIT_HEAD_FILE, "refs/heads/inv@{id", 1, NULL)); }
void test_refs_create__symbolic(void) { /* create a new symbolic reference */ git_reference *new_reference, *looked_up_ref, *resolved_ref; git_repository *repo2; git_oid id; const char *new_head_tracker = "ANOTHER_HEAD_TRACKER"; git_oid_fromstr(&id, current_master_tip); /* Create and write the new symbolic reference */ cl_git_pass(git_reference_symbolic_create(&new_reference, g_repo, new_head_tracker, current_head_target, 0, NULL)); /* Ensure the reference can be looked-up... */ cl_git_pass(git_reference_lookup(&looked_up_ref, g_repo, new_head_tracker)); cl_assert(git_reference_type(looked_up_ref) & GIT_REF_SYMBOLIC); cl_assert(reference_is_packed(looked_up_ref) == 0); cl_assert_equal_s(looked_up_ref->name, new_head_tracker); /* ...peeled.. */ cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref)); cl_assert(git_reference_type(resolved_ref) == GIT_REF_OID); /* ...and that it points to the current master tip */ cl_assert_equal_oid(&id, git_reference_target(resolved_ref)); git_reference_free(looked_up_ref); git_reference_free(resolved_ref); /* Similar test with a fresh new repository */ cl_git_pass(git_repository_open(&repo2, "testrepo")); cl_git_pass(git_reference_lookup(&looked_up_ref, repo2, new_head_tracker)); cl_git_pass(git_reference_resolve(&resolved_ref, looked_up_ref)); cl_assert_equal_oid(&id, git_reference_target(resolved_ref)); git_repository_free(repo2); git_reference_free(new_reference); git_reference_free(looked_up_ref); git_reference_free(resolved_ref); }
/* * call-seq: * reference.target_id -> id * reference.target_id -> ref_name * * Return the target identifier of +reference+. * * If +reference+ is a symbolic reference, it returns the canonical * name of the target reference. * * If +reference+ is a direct reference, it returns the sha id of the target. * * ref1.type #=> :symbolic * ref1.target_id #=> "refs/heads/master" * * ref2.type #=> :direct * ref2.target_id #=> "de5ba987198bcf2518885f0fc1350e5172cded78" */ static VALUE rb_git_ref_target_id(VALUE self) { git_reference *ref; Data_Get_Struct(self, git_reference, ref); if (git_reference_type(ref) == GIT_REF_OID) { return rugged_create_oid(git_reference_target(ref)); } else { return rb_str_new_utf8(git_reference_symbolic_target(ref)); } }
/* * Starting with the reference given by `ref_name`, follows symbolic * references until a direct reference is found and updated the OID * on that direct reference to `oid`. */ int git_reference__update_terminal( git_repository *repo, const char *ref_name, const git_oid *oid, const git_signature *sig, const char *log_message) { git_reference *ref = NULL, *ref2 = NULL; git_signature *who = NULL; const git_signature *to_use; int error = 0; if (!sig && (error = git_reference__log_signature(&who, repo)) < 0) return error; to_use = sig ? sig : who; error = get_terminal(&ref, repo, ref_name, 0); /* found a dangling symref */ if (error == GIT_ENOTFOUND && ref) { assert(git_reference_type(ref) == GIT_REF_SYMBOLIC); giterr_clear(); error = reference__create(&ref2, repo, ref->target.symbolic, oid, NULL, 0, to_use, log_message, NULL, NULL); } else if (error == GIT_ENOTFOUND) { giterr_clear(); error = reference__create(&ref2, repo, ref_name, oid, NULL, 0, to_use, log_message, NULL, NULL); } else if (error == 0) { assert(git_reference_type(ref) == GIT_REF_OID); error = reference__create(&ref2, repo, ref->name, oid, NULL, 1, to_use, log_message, &ref->target.oid, NULL); } git_reference_free(ref2); git_reference_free(ref); git_signature_free(who); return error; }