Example #1
0
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);
}
Example #2
0
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);
}
Example #3
0
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);
}
Example #4
0
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);
}
Example #5
0
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;
}
Example #6
0
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");
}
Example #7
0
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;
}
Example #8
0
/**
 * 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));
}
Example #9
0
/*
 *  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);
	}
}
Example #10
0
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;
}
Example #11
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;
}
Example #12
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");
}
Example #13
0
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);
}
Example #14
0
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);
}
Example #15
0
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);
}
Example #16
0
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;
}
Example #17
0
/**
 * 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;
}
Example #18
0
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);
}
Example #19
0
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);
}
Example #20
0
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);
}
Example #21
0
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");
}
Example #22
0
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);
}
Example #23
0
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);
}
Example #24
0
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);
}
Example #25
0
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);
}
Example #26
0
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;
}
Example #27
0
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));
}
Example #28
0
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);
}
Example #29
0
/*
 *  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));
	}
}
Example #30
0
/*
 * 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;
}