Exemple #1
0
int ssh_certificate_check(git_cert *cert, int valid, const char *host, void *payload)
{
	git_cert_hostkey *key;
	git_oid expected = {{0}}, actual = {{0}};

	GIT_UNUSED(valid);
	GIT_UNUSED(payload);

	cl_assert(_remote_ssh_fingerprint);

	cl_git_pass(git_oid_fromstrp(&expected, _remote_ssh_fingerprint));
	cl_assert_equal_i(GIT_CERT_HOSTKEY_LIBSSH2, cert->cert_type);
	key = (git_cert_hostkey *) cert;

	/*
	 * We need to figure out how long our input was to check for
	 * the type. Here we abuse the fact that both hashes fit into
	 * our git_oid type.
	 */
	if (strlen(_remote_ssh_fingerprint) == 32 && key->type & GIT_CERT_SSH_MD5) {
		memcpy(&actual.id, key->hash_md5, 16);
	} else 	if (strlen(_remote_ssh_fingerprint) == 40 && key->type & GIT_CERT_SSH_SHA1) {
		memcpy(&actual, key->hash_sha1, 20);
	} else {
		cl_fail("Cannot find a usable SSH hash");
	}

	cl_assert(!memcmp(&expected, &actual, 20));

	cl_assert_equal_s("localhost", host);

	return GIT_EUSER;
}
Exemple #2
0
static int note_list_create_cb(
	const git_oid *blob_oid, const git_oid *annotated_obj_id, void *payload)
{
	git_oid expected_note_oid, expected_target_oid;
	struct note_create_payload *notes = payload;
	size_t i;

	for (i = 0; notes[i].note_oid != NULL; i++) {
		cl_git_pass(git_oid_fromstr(&expected_note_oid, notes[i].note_oid));

		if (git_oid_cmp(&expected_note_oid, blob_oid) != 0)
			continue;

		cl_git_pass(git_oid_fromstr(&expected_target_oid, notes[i].object_oid));

		if (git_oid_cmp(&expected_target_oid, annotated_obj_id) != 0)
			continue;

		notes[i].seen = 1;
		return 0;
	}

	cl_fail("Did not see expected note");
	return 0;
}
void verify_remote_refs(const git_remote_head *actual_refs[], size_t actual_refs_len, const expected_ref expected_refs[], size_t expected_refs_len)
{
	size_t i, j = 0;
	git_buf msg = GIT_BUF_INIT;
	const git_remote_head *actual;
	char *oid_str;
	bool master_present = false;

	/* We don't care whether "master" is present on the other end or not */
	for (i = 0; i < actual_refs_len; i++) {
		actual = actual_refs[i];
		if (!strcmp(actual->name, "refs/heads/master")) {
			master_present = true;
			break;
		}
	}

	if (expected_refs_len + (master_present ? 1 : 0) != actual_refs_len)
		goto failed;

	for (i = 0; i < actual_refs_len; i++) {
		actual = actual_refs[i];
		if (master_present && !strcmp(actual->name, "refs/heads/master"))
			continue;

		if (strcmp(expected_refs[j].name, actual->name) ||
			git_oid_cmp(expected_refs[j].oid, &actual->oid))
			goto failed;

		j++;
	}

	return;

failed:
	git_buf_puts(&msg, "Expected and actual refs differ:\nEXPECTED:\n");

	for(i = 0; i < expected_refs_len; i++) {
		cl_assert(oid_str = git_oid_allocfmt(expected_refs[i].oid));
		cl_git_pass(git_buf_printf(&msg, "%s = %s\n", expected_refs[i].name, oid_str));
		git__free(oid_str);
	}

	git_buf_puts(&msg, "\nACTUAL:\n");
	for (i = 0; i < actual_refs_len; i++) {
		actual = actual_refs[i];
		if (master_present && !strcmp(actual->name, "refs/heads/master"))
			continue;

		cl_assert(oid_str = git_oid_allocfmt(&actual->oid));
		cl_git_pass(git_buf_printf(&msg, "%s = %s\n", actual->name, oid_str));
		git__free(oid_str);
	}

	cl_fail(git_buf_cstr(&msg));

	git_buf_free(&msg);
}
Exemple #4
0
static void assert_branch_list_contains(git_strarray *branches, const char* expected_branch_name)
{
	unsigned int i;

	for (i = 0; i < branches->count; i++) {
		if (strcmp(expected_branch_name, branches->strings[i]) == 0)
			return;
	}

	cl_fail("expected branch not found in list.");
}
Exemple #5
0
static int hunk_cb(
	const git_diff_delta *delta,
	const git_diff_hunk *hunk,
	void *payload)
{
	GIT_UNUSED(delta);
	GIT_UNUSED(hunk);
	GIT_UNUSED(payload);

	cl_fail("did not expect hunk callback");
	return 0;
}
Exemple #6
0
static int cb_status__expected_path(const char *p, unsigned int s, void *payload)
{
	const char *expected_path = (const char *)payload;

	GIT_UNUSED(s);

	if (payload == NULL)
		cl_fail("Unexpected path");

	cl_assert_equal_s(expected_path, p);

	return 0;
}
Exemple #7
0
static void assert_branch_has_been_found(struct expectations *findings, const char* expected_branch_name)
{
	int pos = 0;

	for (pos = 0; findings[pos].branch_name; ++pos) {
		if (strcmp(expected_branch_name, findings[pos].branch_name) == 0) {
			cl_assert_equal_i(1, findings[pos].encounters);
			return;
		}
	}

	cl_fail("expected branch not found in list.");
}
Exemple #8
0
static void do_verify_push_status(record_callbacks_data *data, const push_status expected[], const size_t expected_len)
{
	git_vector *actual = &data->statuses;
	push_status *iter;
	bool failed = false;
	size_t i;

	if (expected_len != actual->length)
		failed = true;
	else
		git_vector_foreach(actual, i, iter)
			if (strcmp(expected[i].ref, iter->ref) ||
				(expected[i].success != iter->success) ||
				(expected[i].msg && (!iter->msg || strcmp(expected[i].msg, iter->msg)))) {
				failed = true;
				break;
			}

	if (failed) {
		git_buf msg = GIT_BUF_INIT;

		git_buf_puts(&msg, "Expected and actual push statuses differ:\nEXPECTED:\n");

		for(i = 0; i < expected_len; i++) {
			git_buf_printf(&msg, "%s: %s\n",
				expected[i].ref,
				expected[i].success ? "success" : "failed");
		}

		git_buf_puts(&msg, "\nACTUAL:\n");

		git_vector_foreach(actual, i, iter) {
			if (iter->success)
				git_buf_printf(&msg, "%s: success\n", iter->ref);
			else
				git_buf_printf(&msg, "%s: failed with message: %s", iter->ref, iter->msg);
		}

		cl_fail(git_buf_cstr(&msg));

		git_buf_dispose(&msg);
	}

	git_vector_foreach(actual, i, iter) {
		push_status *s = (push_status *)iter;
		git__free(s->ref);
		git__free(s->msg);
		git__free(s);
	}
Exemple #9
0
static int wildcard_filter_apply(
	git_filter     *self,
	void          **payload,
	git_buf        *to,
	const git_buf  *from,
	const git_filter_source *source)
{
	const char *filtername = *payload;

	if (filtername && strcmp(filtername, "wcflip") == 0)
		return bitflip_filter_apply(self, payload, to, from, source);
	else if (filtername && strcmp(filtername, "wcreverse") == 0)
		return reverse_filter_apply(self, payload, to, from, source);

	cl_fail("Unexpected attribute");
	return GIT_PASSTHROUGH;
}
Exemple #10
0
void test_index_racy__empty_file_after_smudge(void)
{
	git_index *index;
	git_diff *diff;
	git_buf path = GIT_BUF_INIT;
	int i, found_race = 0;
	const git_index_entry *entry;

	/* Make sure we do have a timestamp */
	cl_git_pass(git_repository_index(&index, g_repo));
	cl_git_pass(git_index_write(index));

	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));

	/* Make sure writing the file, adding and rewriting happen in the same second */
	for (i = 0; i < 10; i++) {
		struct stat st;
		cl_git_mkfile(path.ptr, "A");

		cl_git_pass(git_index_add_bypath(index, "A"));
		cl_git_mkfile(path.ptr, "B");
		cl_git_pass(git_index_write(index));

		cl_git_mkfile(path.ptr, "");

		cl_git_pass(p_stat(path.ptr, &st));
		cl_assert(entry = git_index_get_bypath(index, "A", 0));
		if (entry->mtime.seconds == (int32_t) st.st_mtime) {
			found_race = 1;
			break;
		}

	}

	if (!found_race)
		cl_fail("failed to find race after 10 attempts");

	cl_assert_equal_i(0, entry->file_size);

	cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, index, NULL));
	cl_assert_equal_i(1, git_diff_num_deltas(diff));
}
Exemple #11
0
char test_core_merge__compare_with_parents_merge_base(const char * commit_id, const char * filename) {
	char * cmd;
	int readfd;
	asprintf(&cmd,"(cd " REPODIR " ; git diff --name-status $(git merge-base $(git show --pretty=format:%%p %s))..%s | ( grep '\\<%s\\>' || true ) )", commit_id, commit_id, filename);
	if(g_debug) printf("repo_contains: running %s\n", cmd);
	pid_t pid = popen3(cmd, NULL, &readfd, NULL);


	char result=0;
	ssize_t bytes_read = read(readfd,&result,1);

	int status=0;
	waitpid(pid,&status,0);
	free(cmd);

	if(!WIFEXITED(status) || WEXITSTATUS(status)!=0 ) {
		cl_fail("git diff failed");
	}

	if( bytes_read==0 )
		return 0;
	return result;
}
Exemple #12
0
void test_core_merge__demo_create_merge_commit(void) {

	AGBError * error;
	agb_error_new(&error);


	// Here we're going to try to use the merge iterator to create a merge commit that contains the right information.
	// Note - this version does not recurse into directories. (subtrees)
	git_treebuilder * builder;
	git_treebuilder_create(&builder, base_tree);
	AGBMergeIterator * it = agb_merge__create_iterator(head_tree, branch_tree, base_tree, agb_merge_iterator_options_NONE);

	for( ; agb_merge_iterator_is_valid(it) ; agb_merge_iterator_next(it) ) {
        AGBMergeEntry * entry = agb_merge_entry_from_iterator(it);
		int hasLocalChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_LOCAL) );
		int hasRemoteChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_REMOTE) );
		printf("-- %s %d %d\n", agb_merge_entry_name(entry), hasLocalChanged, hasRemoteChanged);

		if( !hasLocalChanged && !hasRemoteChanged) {
			continue;
		}

		if( hasLocalChanged && !hasRemoteChanged) {
			//We want the head version.
			if(agb_merge_entry_id(entry,AGB_MERGE_LOCAL) == NULL) {
				//TODO: Check error message.
				printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) );
				git_treebuilder_remove(builder, agb_merge_entry_name(entry) );
				continue;
			}

			//TODO: Check for error
			printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) );
			int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_LOCAL), agb_merge_entry_filemode(entry,AGB_MERGE_LOCAL) );
            if(ok!=0) {
                printf("Error duting add/update of tree builder: %s\n", giterr_last()->message);
                abort();
            }
            continue;
		}

		if( !hasLocalChanged && hasRemoteChanged) {
			//We want the head version.
			if(agb_merge_entry_id(entry,AGB_MERGE_REMOTE) == NULL) {
				//TODO: Check error message.
				printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) );
				git_treebuilder_remove(builder, agb_merge_entry_name(entry) );
				continue;
			}

			//TODO: Check for error
			printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) );
			int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_REMOTE), agb_merge_entry_filemode(entry,AGB_MERGE_REMOTE) );
			if(ok!=0) {
                printf("Error duting add/update of tree builder: %s\n", giterr_last()->message);
                abort();
            }
            continue;
		}

			printf("CONFLICT %s in tree\n", agb_merge_entry_name(entry) );
		//TODO: CONFLICT - Handle it!

	}

	// Our tree builder should now be full...
	// Lets write it out to a tree
	//
	//TODO: Check for errors
	git_oid new_tree_oid = {};
	git_treebuilder_write(&new_tree_oid, repo, builder);

	char hexid[GIT_OID_HEXSZ+1];
	printf("Tree SHA is %s\n", git_oid_tostr(hexid,GIT_OID_HEXSZ+1, &new_tree_oid));

	git_tree * new_tree = NULL;
	git_tree_lookup(&new_tree, repo, &new_tree_oid);

	// Now we need to create the commit.
    const git_commit** parents = (const git_commit**)malloc(sizeof(git_commit*)*2);

	parents[0] = head_commit;
	parents[1] = branch_commit;


	git_signature * author_signature = NULL;

	// Time since epoch
	// TODO: Get these correctly -
	// Could use git_signature_now instead...
	{

		git_time_t author_time = time(NULL);
		int timezone_offset = 0;
		int ok;

		if((ok=git_signature_new(&author_signature,"Someone","*****@*****.**", author_time, timezone_offset))!=0) {
			agb__error_translate(error,"git_signature_new failed",ok);
			goto cleanup_error;
		}
	}



	git_oid commit_id;
	int ok = git_commit_create(
				&commit_id,
				repo,
				NULL,
				author_signature,
				author_signature,
				"UTF-8",
				"An exciting commit",
				new_tree,
			       	2, //Two parents
				parents
				);
	if(ok!=0) {
		agb__error_translate(error,"git_commit_create failed",ok);
		goto cleanup_error;
	}

	// Then update the refs.
	//TODO: Do we need to release this ref?
	git_reference * ref;
	ok = git_reference_create_matching(
			&ref,
			repo,
		   	"refs/heads/branch_c",
			&commit_id,
			1,
			NULL,
			author_signature,
			"merged by libagb");

	if(ok!=0) {
		agb__error_translate(error,"git_reference_create failed",ok);
		goto cleanup_error;
	}

	git_signature_free(author_signature);

	// Now check we got the expected files
	cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_a.txt"));
	cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_b.txt"));

	return;

cleanup_error:

	printf("ERROR: %s\n",error->message);

	if(author_signature) {
		git_signature_free(author_signature);
	}
	cl_fail(error->message);


}