Beispiel #1
0
void test_stash_drop__dropping_an_entry_rewrites_reflog_history(void)
{
	git_reference *stash;
	git_reflog *reflog;
	const git_reflog_entry *entry;
	git_oid oid;
	size_t count;

	push_three_states();

	cl_git_pass(git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE));

	cl_git_pass(git_reflog_read(&reflog, stash));
	entry = git_reflog_entry_byindex(reflog, 1);

	git_oid_cpy(&oid, git_reflog_entry_id_old(entry));
	count = git_reflog_entrycount(reflog);

	git_reflog_free(reflog);

	cl_git_pass(git_stash_drop(repo, 1));

	cl_git_pass(git_reflog_read(&reflog, stash));
	entry = git_reflog_entry_byindex(reflog, 0);

	cl_assert_equal_i(0, git_oid_cmp(&oid, git_reflog_entry_id_old(entry)));
	cl_assert_equal_sz(count - 1, git_reflog_entrycount(reflog));

	git_reflog_free(reflog);

	git_reference_free(stash);
}
Beispiel #2
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);
}
Beispiel #3
0
static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, unsigned int identifier)
{
	git_reflog *reflog;
	int error = -1;
	unsigned int numentries;
	const git_reflog_entry *entry;
	bool search_by_pos = (identifier <= 100000000);

	if (git_reflog_read(&reflog, ref) < 0)
		return -1;

	numentries  = git_reflog_entrycount(reflog);

	if (search_by_pos) {
		if (numentries < identifier + 1) {
			giterr_set(
				GITERR_REFERENCE,
				"Reflog for '%s' has only %d entries, asked for %d",
				git_reference_name(ref),
				numentries,
				identifier);

			error = GIT_ENOTFOUND;
			goto cleanup;
		}

		entry = git_reflog_entry_byindex(reflog, identifier);
		git_oid_cpy(oid, git_reflog_entry_oidold(entry));
		error = 0;
		goto cleanup;

	} else {
		int i;
		git_time commit_time;

		for (i = numentries - 1; i >= 0; i--) {
			entry = git_reflog_entry_byindex(reflog, i);
			commit_time = git_reflog_entry_committer(entry)->when;
					
			if (commit_time.time - identifier > 0)
				continue;

			git_oid_cpy(oid, git_reflog_entry_oidnew(entry));
			error = 0;
			goto cleanup;
		}

		error = GIT_ENOTFOUND;
	}

cleanup:
	git_reflog_free(reflog);
	return error;
}
Beispiel #4
0
static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t identifier)
{
	git_reflog *reflog;
	int error = -1;
	size_t numentries;
	const git_reflog_entry *entry;
	bool search_by_pos = (identifier <= 100000000);

	if (git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref)) < 0)
		return -1;

	numentries = git_reflog_entrycount(reflog);

	if (search_by_pos) {
		if (numentries < identifier + 1) {
			giterr_set(
				GITERR_REFERENCE,
				"Reflog for '%s' has only %"PRIuZ" entries, asked for %"PRIuZ,
				git_reference_name(ref), numentries, identifier);

			error = GIT_ENOTFOUND;
			goto cleanup;
		}

		entry = git_reflog_entry_byindex(reflog, identifier);
		git_oid_cpy(oid, git_reflog_entry_id_new(entry));
		error = 0;
		goto cleanup;

	} else {
		size_t i;
		git_time commit_time;

		for (i = 0; i < numentries; i++) {
			entry = git_reflog_entry_byindex(reflog, i);
			commit_time = git_reflog_entry_committer(entry)->when;

			if (commit_time.time > (git_time_t)identifier)
				continue;

			git_oid_cpy(oid, git_reflog_entry_id_new(entry));
			error = 0;
			goto cleanup;
		}

		error = GIT_ENOTFOUND;
	}

cleanup:
	git_reflog_free(reflog);
	return error;
}
Beispiel #5
0
/*
 *  call-seq:
 *    reference.log -> [reflog_entry, ...]
 *
 *  Return an array with the log of all modifications to this reference
 *
 *  Each +reflog_entry+ is a hash with the following keys:
 *
 *  - +:id_old+: previous OID before the change
 *  - +:id_new+: OID after the change
 *  - +:committer+: author of the change
 *  - +:message+: message for the change
 *
 *  Example:
 *
 *    reference.log #=> [
 *    # {
 *    #  :id_old => nil,
 *    #  :id_new => '9d09060c850defbc7711d08b57def0d14e742f4e',
 *    #  :committer => {:name => 'Vicent Marti', :email => {'*****@*****.**'}},
 *    #  :message => 'created reference'
 *    # }, ... ]
 */
static VALUE rb_git_reflog(VALUE self)
{
	git_reflog *reflog;
	git_reference *ref;
	int error;
	VALUE rb_log;
	size_t i, ref_count;

	Data_Get_Struct(self, git_reference, ref);

	error = git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref));
	rugged_exception_check(error);

	ref_count = git_reflog_entrycount(reflog);
	rb_log = rb_ary_new2(ref_count);

	for (i = 0; i < ref_count; ++i) {
		const git_reflog_entry *entry =
			git_reflog_entry_byindex(reflog, ref_count - i - 1);

		rb_ary_push(rb_log, reflog_entry_new(entry));
	}

	git_reflog_free(reflog);
	return rb_log;
}
Beispiel #6
0
void test_refs_reflog_messages__creating_a_direct_reference(void)
{
	git_reference *reference;
	git_oid id;
	git_reflog *reflog;
	const git_reflog_entry *entry;

	const char *name = "refs/heads/new-head";
	const char *message = "You've been logged, mate!";

	cl_git_pass(git_reference_name_to_id(&id, g_repo, "HEAD"));

	cl_git_pass(git_reference_create(&reference, g_repo, name, &id, 0, message));

	cl_git_pass(git_reflog_read(&reflog, g_repo, name));
	cl_assert_equal_sz(1, git_reflog_entrycount(reflog));

	entry = git_reflog_entry_byindex(reflog, 0);
	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0);
	cl_assert_equal_oid(&id, &entry->oid_cur);
	cl_assert_equal_s(message, entry->msg);

	git_reflog_free(reflog);
	git_reference_free(reference);
}
Beispiel #7
0
void test_refs_settargetwithlog__updating_a_direct_reference_adds_a_reflog_entry(void)
{
	git_reference *reference, *reference_out;
	git_oid current_id, target_id;
	git_signature *signature;
	git_reflog *reflog;
	const git_reflog_entry *entry;

	const char *message = "You've been logged, mate!";

	git_oid_fromstr(&current_id, br2_tip);
	git_oid_fromstr(&target_id, master_tip);

	cl_git_pass(git_reference_lookup(&reference, g_repo, br2_name));

	cl_git_pass(git_signature_now(&signature, "foo", "foo@bar"));

	cl_git_pass(git_reference_set_target(
		&reference_out, reference, &target_id, signature, message));

	cl_git_pass(git_reflog_read(&reflog, g_repo, br2_name));

	entry = git_reflog_entry_byindex(reflog, 0);
	cl_assert(git_oid_cmp(&current_id, &entry->oid_old) == 0);
	cl_assert(git_oid_cmp(&target_id, &entry->oid_cur) == 0);
	cl_assert_equal_s(message, entry->msg);

	git_reflog_free(reflog);
	git_reference_free(reference_out);
	git_reference_free(reference);
	git_signature_free(signature);
}
Beispiel #8
0
void test_network_remote_local__fetch_default_reflog_message(void)
{
    char *refspec_strings[] = {
        "master:remotes/sloppy/master",
    };
    git_strarray array = {
        refspec_strings,
        1,
    };

    git_reflog *log;
    const git_reflog_entry *entry;
    char expected_reflog_msg[1024];

    connect_to_local_repository(cl_fixture("testrepo.git"));

    cl_git_pass(git_remote_fetch(remote, &array, NULL, NULL));

    cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
    cl_assert_equal_i(1, git_reflog_entrycount(log));
    entry = git_reflog_entry_byindex(log, 0);
    cl_assert_equal_s("*****@*****.**", git_reflog_entry_committer(entry)->email);

    sprintf(expected_reflog_msg, "fetch %s", git_remote_url(remote));
    cl_assert_equal_s(expected_reflog_msg, git_reflog_entry_message(entry));

    git_reflog_free(log);
}
Beispiel #9
0
void test_refs_branches_create__default_reflog_message(void)
{
	git_reflog *log;
	const git_reflog_entry *entry;
	git_signature *sig;
	git_config *cfg;

	cl_git_pass(git_repository_config(&cfg, repo));
	cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar"));
	cl_git_pass(git_config_set_string(cfg, "user.email", "*****@*****.**"));
	git_config_free(cfg);

	cl_git_pass(git_signature_default(&sig, repo));

	retrieve_known_commit(&target, repo);
	cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false, NULL, NULL));
	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME));

	entry = git_reflog_entry_byindex(log, 0);
	cl_assert_equal_s("Branch: created", git_reflog_entry_message(entry));
	cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email);

	git_reflog_free(log);
	git_signature_free(sig);
}
Beispiel #10
0
PyObject *
RefLogIter_iternext(RefLogIter *self)
{
    const git_reflog_entry *entry;
    RefLogEntry *py_entry;
    int err;

    if (self->i < self->size) {
        entry = git_reflog_entry_byindex(self->reflog, self->i);
        py_entry = PyObject_New(RefLogEntry, &RefLogEntryType);

        py_entry->oid_old = git_oid_to_python(git_reflog_entry_id_old(entry));
        py_entry->oid_new = git_oid_to_python(git_reflog_entry_id_new(entry));
        py_entry->message = strdup(git_reflog_entry_message(entry));
        err = git_signature_dup(&py_entry->signature,
                                git_reflog_entry_committer(entry));
        if (err < 0)
            return Error_set(err);

        ++(self->i);

        return (PyObject*) py_entry;
    }

    PyErr_SetNone(PyExc_StopIteration);
    return NULL;
}
Beispiel #11
0
static void test_reflog(git_repository *repo, size_t idx,
                        const char *old_spec, const char *new_spec,
                        const char *email, const char *message)
{
    git_reflog *log;
    const git_reflog_entry *entry;

    cl_git_pass(git_reflog_read(&log, repo, "HEAD"));
    entry = git_reflog_entry_byindex(log, idx);

    if (old_spec) {
        git_object *obj;
        cl_git_pass(git_revparse_single(&obj, repo, old_spec));
        cl_assert_equal_oid(git_object_id(obj), git_reflog_entry_id_old(entry));
        git_object_free(obj);
    }
    if (new_spec) {
        git_object *obj;
        cl_git_pass(git_revparse_single(&obj, repo, new_spec));
        cl_assert_equal_oid(git_object_id(obj), git_reflog_entry_id_new(entry));
        git_object_free(obj);
    }

    if (email) {
        cl_assert_equal_s(email, git_reflog_entry_committer(entry)->email);
    }
    if (message) {
        cl_assert_equal_s(message, git_reflog_entry_message(entry));
    }

    git_reflog_free(log);
}
Beispiel #12
0
void test_network_remote_local__fetch(void)
{
    char *refspec_strings[] = {
        "master:remotes/sloppy/master",
    };
    git_strarray array = {
        refspec_strings,
        1,
    };

    git_reflog *log;
    const git_reflog_entry *entry;
    git_reference *ref;

    connect_to_local_repository(cl_fixture("testrepo.git"));

    cl_git_pass(git_remote_fetch(remote, &array, NULL, "UPDAAAAAATE!!"));

    cl_git_pass(git_reference_lookup(&ref, repo, "refs/remotes/sloppy/master"));
    git_reference_free(ref);

    cl_git_pass(git_reflog_read(&log, repo, "refs/remotes/sloppy/master"));
    cl_assert_equal_i(1, git_reflog_entrycount(log));
    entry = git_reflog_entry_byindex(log, 0);
    cl_assert_equal_s("*****@*****.**", git_reflog_entry_committer(entry)->email);
    cl_assert_equal_s("UPDAAAAAATE!!", git_reflog_entry_message(entry));

    git_reflog_free(log);
}
Beispiel #13
0
int git_reflog_drop(git_reflog *reflog, size_t idx, int rewrite_previous_entry)
{
	size_t entrycount;
	git_reflog_entry *entry, *previous;

	entrycount = git_reflog_entrycount(reflog);

	entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);

	if (entry == NULL) {
		giterr_set(GITERR_REFERENCE, "No reflog entry at index "PRIuZ, idx);
		return GIT_ENOTFOUND;
	}

	git_reflog_entry__free(entry);

	if (git_vector_remove(
			&reflog->entries, reflog_inverse_index(idx, entrycount)) < 0)
		return -1;

	if (!rewrite_previous_entry)
		return 0;

	/* No need to rewrite anything when removing the most recent entry */
	if (idx == 0)
		return 0;

	/* Have the latest entry just been dropped? */
	if (entrycount == 1)
		return 0;

	entry = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx - 1);

	/* If the oldest entry has just been removed... */
	if (idx == entrycount - 1) {
		/* ...clear the oid_old member of the "new" oldest entry */
		if (git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO) < 0)
			return -1;

		return 0;
	}

	previous = (git_reflog_entry *)git_reflog_entry_byindex(reflog, idx);
	git_oid_cpy(&entry->oid_old, &previous->oid_cur);

	return 0;
}
Beispiel #14
0
ERL_NIF_TERM
geef_reflog_read(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
	git_reflog *reflog;
	geef_repository *repo;
	ErlNifBinary bin;
	int error;
	size_t count, i;
	ERL_NIF_TERM list;

	if (!enif_get_resource(env, argv[0], geef_repository_type, (void **) &repo))
		return enif_make_badarg(env);

	if (!enif_inspect_iolist_as_binary(env, argv[1], &bin))
		return enif_make_badarg(env);

	if (!geef_terminate_binary(&bin))
		return geef_oom(env);

	if ((error = git_reflog_read(&reflog, repo->repo, (char *)bin.data)) < 0)
		return geef_error(env);

	count = git_reflog_entrycount(reflog);
	list = enif_make_list(env, 0);

	for (i = count; i > 0; i--) {
		ErlNifBinary id_old, id_new, message;
		ERL_NIF_TERM tentry, name, email, time, offset;
		const git_reflog_entry *entry;

		entry = git_reflog_entry_byindex(reflog, i-1);

		if (geef_oid_bin(&id_old, git_reflog_entry_id_old(entry)))
			goto on_oom;

		if (geef_oid_bin(&id_new, git_reflog_entry_id_new(entry)))
			goto on_oom;

		if (geef_signature_to_erl(&name, &email, &time, &offset,
					  env, git_reflog_entry_committer(entry)))
			goto on_oom;

		if (geef_string_to_bin(&message, git_reflog_entry_message(entry)))
			goto on_oom;

		tentry = enif_make_tuple7(env, name, email, time, offset,
					  enif_make_binary(env, &id_old),
					  enif_make_binary(env, &id_new),
					  enif_make_binary(env, &message));
		list = enif_make_list_cell(env, tentry, list);
	}

	git_reflog_free(reflog);
	return enif_make_tuple2(env, atoms.ok, list);

on_oom:
	git_reflog_free(reflog);
	return geef_oom(env);
}
Beispiel #15
0
void test_rebase_merge__commit(void)
{
	git_rebase *rebase;
	git_reference *branch_ref, *upstream_ref;
	git_annotated_commit *branch_head, *upstream_head;
	git_rebase_operation *rebase_operation;
	git_oid commit_id, tree_id, parent_id;
	git_signature *author;
	git_commit *commit;
	git_reflog *reflog;
	const git_reflog_entry *reflog_entry;

	cl_git_pass(git_reference_lookup(&branch_ref, repo, "refs/heads/beef"));
	cl_git_pass(git_reference_lookup(&upstream_ref, repo, "refs/heads/master"));

	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));
	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
		NULL, NULL));

	cl_git_pass(git_commit_lookup(&commit, repo, &commit_id));

	git_oid_fromstr(&parent_id, "efad0b11c47cb2f0220cbd6f5b0f93bb99064b00");
	cl_assert_equal_i(1, git_commit_parentcount(commit));
	cl_assert_equal_oid(&parent_id, git_commit_parent_id(commit, 0));

	git_oid_fromstr(&tree_id, "4461379789c777d2a6c1f2ee0e9d6c86731b9992");
	cl_assert_equal_oid(&tree_id, git_commit_tree_id(commit));

	cl_assert_equal_s(NULL, git_commit_message_encoding(commit));
	cl_assert_equal_s("Modification 1 to beef\n", git_commit_message(commit));

	cl_git_pass(git_signature_new(&author,
		"Edward Thomson", "*****@*****.**", 1405621769, 0-(4*60)));
	cl_assert(git_signature__equal(author, git_commit_author(commit)));

	cl_assert(git_signature__equal(signature, git_commit_committer(commit)));

	/* 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(&parent_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: Modification 1 to beef", git_reflog_entry_message(reflog_entry));

	git_reflog_free(reflog);
	git_signature_free(author);
	git_commit_free(commit);
	git_annotated_commit_free(branch_head);
	git_annotated_commit_free(upstream_head);
	git_reference_free(branch_ref);
	git_reference_free(upstream_ref);
	git_rebase_free(rebase);
}
Beispiel #16
0
void test_refs_branches_create__default_reflog_message(void)
{
	git_reflog *log;
	git_buf buf = GIT_BUF_INIT;
	const git_reflog_entry *entry;
	git_annotated_commit *annotated;
	git_signature *sig;
	git_config *cfg;

	cl_git_pass(git_repository_config(&cfg, repo));
	cl_git_pass(git_config_set_string(cfg, "user.name", "Foo Bar"));
	cl_git_pass(git_config_set_string(cfg, "user.email", "*****@*****.**"));
	git_config_free(cfg);

	cl_git_pass(git_signature_default(&sig, repo));

	retrieve_known_commit(&target, repo);
	cl_git_pass(git_branch_create(&branch, repo, NEW_BRANCH_NAME, target, false));
	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME));

	entry = git_reflog_entry_byindex(log, 0);
	cl_git_pass(git_buf_printf(&buf, "branch: Created from %s", git_oid_tostr_s(git_commit_id(target))));
	cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry));
	cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email);

	cl_git_pass(git_reference_remove(repo, "refs/heads/" NEW_BRANCH_NAME));
	git_reference_free(branch);
	git_reflog_free(log);
	git_buf_clear(&buf);

	cl_git_pass(git_annotated_commit_from_revspec(&annotated, repo, "e90810b8df3"));
	cl_git_pass(git_branch_create_from_annotated(&branch, repo, NEW_BRANCH_NAME, annotated, true));
	cl_git_pass(git_reflog_read(&log, repo, "refs/heads/" NEW_BRANCH_NAME));

	entry = git_reflog_entry_byindex(log, 0);
	cl_git_pass(git_buf_printf(&buf, "branch: Created from e90810b8df3"));
	cl_assert_equal_s(git_buf_cstr(&buf), git_reflog_entry_message(entry));
	cl_assert_equal_s(sig->email, git_reflog_entry_committer(entry)->email);

	git_annotated_commit_free(annotated);
	git_buf_free(&buf);
	git_reflog_free(log);
	git_signature_free(sig);
}
Beispiel #17
0
void test_refs_reflog_drop__can_drop_an_entry_and_rewrite_the_log_history(void)
{
	const git_reflog_entry *before_current;
	const git_reflog_entry *after_current;
	git_oid before_current_old_oid, before_current_cur_oid;

	cl_assert(entrycount > 4);

	before_current = git_reflog_entry_byindex(g_reflog, 2);
	git_oid_cpy(&before_current_old_oid, &before_current->oid_old);
	git_oid_cpy(&before_current_cur_oid, &before_current->oid_cur);

	cl_git_pass(git_reflog_drop(g_reflog, 2, 1));
	cl_assert_equal_i(entrycount - 1, git_reflog_entrycount(g_reflog));

	after_current = git_reflog_entry_byindex(g_reflog, 2);

	cl_assert_equal_i(0, git_oid_cmp(&before_current_old_oid, &after_current->oid_old));
	cl_assert(0 != git_oid_cmp(&before_current_cur_oid, &after_current->oid_cur));
}
Beispiel #18
0
void test_refs_reflog_drop__can_drop_the_oldest_entry_and_rewrite_the_log_history(void)
{
	const git_reflog_entry *entry;

	cl_assert(entrycount > 2);

	cl_git_pass(git_reflog_drop(g_reflog, 0, 1));
	cl_assert_equal_i(entrycount - 1, git_reflog_entrycount(g_reflog));

	entry = git_reflog_entry_byindex(g_reflog, 0);
	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0);
}
Beispiel #19
0
void test_refs_reflog_drop__can_drop_the_oldest_entry(void)
{
	const git_reflog_entry *entry;

	cl_assert(entrycount > 2);

	cl_git_pass(git_reflog_drop(g_reflog, entrycount - 1, 0));
	cl_assert_equal_sz(entrycount - 1, git_reflog_entrycount(g_reflog));

	entry = git_reflog_entry_byindex(g_reflog, entrycount - 2);
	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) != 0);
}
Beispiel #20
0
static void check_last_reflog_entry(const char *email, const char *message)
{
    git_reflog *log;
    const git_reflog_entry *entry;

    cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
    cl_assert(git_reflog_entrycount(log) > 0);
    entry = git_reflog_entry_byindex(log, 0);
    if (email)
        cl_assert_equal_s(email, git_reflog_entry_committer(entry)->email);
    if (message)
        cl_assert_equal_s(message, git_reflog_entry_message(entry));
    git_reflog_free(log);
}
Beispiel #21
0
static void assert_appends(const git_signature *committer, const git_oid *oid)
{
	git_repository *repo2;
	git_reference *lookedup_ref;
	git_reflog *reflog;
	const git_reflog_entry *entry;

	/* Reopen a new instance of the repository */
	cl_git_pass(git_repository_open(&repo2, "testrepo.git"));

	/* Lookup the previously created branch */
	cl_git_pass(git_reference_lookup(&lookedup_ref, repo2, new_ref));

	/* Read and parse the reflog for this branch */
	cl_git_pass(git_reflog_read(&reflog, repo2, new_ref));
	cl_assert_equal_i(3, (int)git_reflog_entrycount(reflog));

	/* The first one was the creation of the branch */
	entry = git_reflog_entry_byindex(reflog, 2);
	cl_assert(git_oid_streq(&entry->oid_old, GIT_OID_HEX_ZERO) == 0);

	entry = git_reflog_entry_byindex(reflog, 1);
	assert_signature(committer, entry->committer);
	cl_assert(git_oid_cmp(oid, &entry->oid_old) == 0);
	cl_assert(git_oid_cmp(oid, &entry->oid_cur) == 0);
	cl_assert(entry->msg == NULL);

	entry = git_reflog_entry_byindex(reflog, 0);
	assert_signature(committer, entry->committer);
	cl_assert(git_oid_cmp(oid, &entry->oid_cur) == 0);
	cl_assert_equal_s(commit_msg, entry->msg);

	git_reflog_free(reflog);
	git_repository_free(repo2);

	git_reference_free(lookedup_ref);
}
Beispiel #22
0
/**
 * List the reflog within a specified reference.
 *
 * @param repo S4 class git_repository
 * @param ref Reference to read from.
 * @return VECXSP with S4 objects of class git_reflog
 */
SEXP git2r_reflog_list(SEXP repo, SEXP ref)
{
    int err;
    size_t i, n;
    SEXP result = R_NilValue;
    git_reflog *reflog = NULL;
    git_repository *repository = NULL;

    if (git2r_arg_check_string(ref))
        git2r_error(__func__, NULL, "'ref'", git2r_err_string_arg);

    repository = git2r_repository_open(repo);
    if (!repository)
        git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL);

    err = git_reflog_read(&reflog, repository, CHAR(STRING_ELT(ref, 0)));
    if (err)
        goto cleanup;

    n = git_reflog_entrycount(reflog);
    PROTECT(result = allocVector(VECSXP, n));
    for (i = 0; i < n; i++) {
        const git_reflog_entry *entry = git_reflog_entry_byindex(reflog, i);

        if (entry) {
            SEXP item;

            SET_VECTOR_ELT(result,
                           i,
                           item = NEW_OBJECT(MAKE_CLASS("git_reflog_entry")));
            git2r_reflog_entry_init(entry, i, repo, ref, item);
        }
    }

cleanup:
    if (reflog)
        git_reflog_free(reflog);

    if (repository)
        git_repository_free(repository);

    if (R_NilValue != result)
        UNPROTECT(1);

    if (err)
        git2r_error(__func__, giterr_last(), NULL, NULL);

    return result;
}
Beispiel #23
0
void test_rebase_merge__finish_with_ids(void)
{
	git_rebase *rebase;
	git_reference *head_ref;
	git_oid branch_id, upstream_id;
	git_annotated_commit *branch_head, *upstream_head;
	git_rebase_operation *rebase_operation;
	git_oid commit_id;
	git_reflog *reflog;
	const git_reflog_entry *reflog_entry;
	int error;

	cl_git_pass(git_oid_fromstr(&branch_id, "d616d97082eb7bb2dc6f180a7cca940993b7a56f"));
	cl_git_pass(git_oid_fromstr(&upstream_id, "f87d14a4a236582a0278a916340a793714256864"));

	cl_git_pass(git_annotated_commit_lookup(&branch_head, repo, &branch_id));
	cl_git_pass(git_annotated_commit_lookup(&upstream_head, repo, &upstream_id));

	cl_git_pass(git_rebase_init(&rebase, repo, branch_head, upstream_head, NULL, NULL));

	cl_git_pass(git_rebase_next(&rebase_operation, rebase));
	cl_git_pass(git_rebase_commit(&commit_id, rebase, NULL, signature,
		NULL, NULL));

	cl_git_fail(error = git_rebase_next(&rebase_operation, rebase));
	cl_assert_equal_i(GIT_ITEROVER, error);

	cl_git_pass(git_rebase_finish(rebase, signature));

	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_OID, git_reference_type(head_ref));
	cl_assert_equal_oid(&commit_id, git_reference_target(head_ref));

	/* reflogs are not updated as if we were operating on proper
	 * branches.  check that the last reflog entry is the rebase.
	 */
	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_new(reflog_entry));
	cl_assert_equal_s("rebase: Modification 3 to gravy", 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_rebase_free(rebase);
}
Beispiel #24
0
static void assert_correct_reflog(const char *name)
{
	git_reflog *log;
	const git_reflog_entry *entry;
	char expected_log_message[128] = {0};

	sprintf(expected_log_message, "clone: from %s", cl_git_fixture_url("testrepo.git"));

	cl_git_pass(git_reflog_read(&log, g_repo, name));
	cl_assert_equal_i(1, git_reflog_entrycount(log));
	entry = git_reflog_entry_byindex(log, 0);
	cl_assert_equal_s(expected_log_message, git_reflog_entry_message(entry));

	git_reflog_free(log);
}
Beispiel #25
0
int git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg)
{
	git_reflog_entry *entry;
	const git_reflog_entry *previous;
	const char *newline;

	assert(reflog && new_oid && committer);

	entry = git__calloc(1, sizeof(git_reflog_entry));
	GITERR_CHECK_ALLOC(entry);

	if ((git_signature_dup(&entry->committer, committer)) < 0)
		goto cleanup;

	if (msg != NULL) {
		if ((entry->msg = git__strdup(msg)) == NULL)
			goto cleanup;

		newline = strchr(msg, '\n');

		if (newline) {
			if (newline[1] != '\0') {
				giterr_set(GITERR_INVALID, "Reflog message cannot contain newline");
				goto cleanup;
			}

			entry->msg[newline - msg] = '\0';
		}
	}

	previous = git_reflog_entry_byindex(reflog, 0);

	if (previous == NULL)
		git_oid_fromstr(&entry->oid_old, GIT_OID_HEX_ZERO);
	else
		git_oid_cpy(&entry->oid_old, &previous->oid_cur);

	git_oid_cpy(&entry->oid_cur, new_oid);

	if (git_vector_insert(&reflog->entries, entry) < 0)
		goto cleanup;

	return 0;

cleanup:
	git_reflog_entry__free(entry);
	return -1;
}
Beispiel #26
0
int git_stash_drop(
	git_repository *repo,
	size_t index)
{
	git_reference *stash;
	git_reflog *reflog = NULL;
	size_t max;
	int error;

	if ((error = git_reference_lookup(&stash, repo, GIT_REFS_STASH_FILE)) < 0)
		return error;

	if ((error = git_reflog_read(&reflog, stash)) < 0)
		goto cleanup;

	max = git_reflog_entrycount(reflog);

	if (index > max - 1) {
		error = GIT_ENOTFOUND;
		giterr_set(GITERR_STASH, "No stashed state at position %" PRIuZ, index);
		goto cleanup;
	}

	if ((error = git_reflog_drop(reflog, index, true)) < 0)
		goto cleanup;

	if ((error = git_reflog_write(reflog)) < 0)
		goto cleanup;

	if (max == 1) {
		error = git_reference_delete(stash);
		git_reference_free(stash);
		stash = NULL;
	} else if (index == 0) {
		const git_reflog_entry *entry;

		entry = git_reflog_entry_byindex(reflog, 0);

		git_reference_free(stash);
		error = git_reference_create(&stash, repo, GIT_REFS_STASH_FILE, &entry->oid_cur, 1);
	}

cleanup:
	git_reference_free(stash);
	git_reflog_free(reflog);
	return error;
}
Beispiel #27
0
/**
 * ggit_reflog_get_entry_from_index:
 * @reflog: a #GgitReflog.
 * @idx: the position to lookup.
 *
 * Gets the #GgitReflogEntry at @idx in @reflog, or %NULL if not found.
 *
 * Returns: (transfer full) (nullable): the reflog entry at the index, or %NULL if not found.
 */
GgitReflogEntry *
ggit_reflog_get_entry_from_index (GgitReflog *reflog,
                                  guint       idx)
{
	const git_reflog_entry *reflog_entry;

	g_return_val_if_fail (reflog != NULL, NULL);

	reflog_entry = git_reflog_entry_byindex (reflog->reflog, idx);

	if (reflog_entry == NULL)
	{
		return NULL;
	}

	return _ggit_reflog_entry_wrap (reflog_entry);
}
Beispiel #28
0
void test_refs_rename__writes_to_reflog(void)
{
	git_reference *ref, *new_ref;
	git_reflog *log;
	const git_reflog_entry *entry;

	cl_git_pass(git_reference_lookup(&ref, g_repo, ref_master_name));
	cl_git_pass(git_reference_rename(&new_ref, ref, ref_one_name_new, false,
				"message"));
	cl_git_pass(git_reflog_read(&log, g_repo, git_reference_name(new_ref)));
	entry = git_reflog_entry_byindex(log, 0);
	cl_assert_equal_s("message", git_reflog_entry_message(entry));
	cl_assert_equal_s("*****@*****.**", git_reflog_entry_committer(entry)->email);

	git_reflog_free(log);
	git_reference_free(ref);
	git_reference_free(new_ref);
}
Beispiel #29
0
static void test_abort(git_annotated_commit *branch, git_annotated_commit *onto)
{
	git_rebase *rebase;
	git_reference *head_ref, *branch_ref = NULL;
	git_signature *signature;
	git_status_list *statuslist;
	git_reflog *reflog;
	const git_reflog_entry *reflog_entry;

	cl_git_pass(git_rebase_open(&rebase, repo));
	cl_git_pass(git_signature_new(&signature, "Rebaser", "*****@*****.**", 1404157834, -400));
	cl_git_pass(git_rebase_abort(rebase, signature));

	cl_assert_equal_i(GIT_REPOSITORY_STATE_NONE, git_repository_state(repo));

	/* Make sure the refs are updated appropriately */
	cl_git_pass(git_reference_lookup(&head_ref, repo, "HEAD"));

	if (branch->ref_name == NULL)
		cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(head_ref));
	else {
		cl_assert_equal_s("refs/heads/beef", git_reference_symbolic_target(head_ref));
		cl_git_pass(git_reference_lookup(&branch_ref, repo, git_reference_symbolic_target(head_ref)));
		cl_assert_equal_oid(git_annotated_commit_id(branch), git_reference_target(branch_ref));
	}

	git_status_list_new(&statuslist, repo, NULL);
	cl_assert_equal_i(0, git_status_list_entrycount(statuslist));
	git_status_list_free(statuslist);

	/* 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(git_annotated_commit_id(onto), git_reflog_entry_id_old(reflog_entry));
	cl_assert_equal_oid(git_annotated_commit_id(branch), git_reflog_entry_id_new(reflog_entry));
	cl_assert_equal_s("rebase: aborting", git_reflog_entry_message(reflog_entry));

	git_reflog_free(reflog);
	git_reference_free(head_ref);
	git_reference_free(branch_ref);
	git_signature_free(signature);
	git_rebase_free(rebase);
}
Beispiel #30
0
static void assert_head_reflog(git_repository *repo, size_t idx,
                               const char *old_id, const char *new_id, const char *message)
{
    git_reflog *log;
    const git_reflog_entry *entry;
    char id_str[GIT_OID_HEXSZ + 1] = {0};

    cl_git_pass(git_reflog_read(&log, repo, GIT_HEAD_FILE));
    entry = git_reflog_entry_byindex(log, idx);

    git_oid_fmt(id_str, git_reflog_entry_id_old(entry));
    cl_assert_equal_s(old_id, id_str);

    git_oid_fmt(id_str, git_reflog_entry_id_new(entry));
    cl_assert_equal_s(new_id, id_str);

    cl_assert_equal_s(message, git_reflog_entry_message(entry));

    git_reflog_free(log);
}