Exemple #1
0
void test_refs_delete__packed_only(void)
{
   // can delete a just packed reference
	git_reference *ref;
	git_refdb *refdb;
	git_oid id;
	const char *new_ref = "refs/heads/new_ref";

	git_oid_fromstr(&id, current_master_tip);

	/* Create and write the new object id reference */
	cl_git_pass(git_reference_create(&ref, g_repo, new_ref, &id, 0));
	git_reference_free(ref);

	/* Lookup the reference */
	cl_git_pass(git_reference_lookup(&ref, g_repo, new_ref));

	/* Ensure it's a loose reference */
	cl_assert(reference_is_packed(ref) == 0);

	/* Pack all existing references */
	cl_git_pass(git_repository_refdb(&refdb, g_repo));
	cl_git_pass(git_refdb_compress(refdb));

	/* Reload the reference from disk */
	git_reference_free(ref);
	cl_git_pass(git_reference_lookup(&ref, g_repo, new_ref));

	/* Ensure it's a packed reference */
	cl_assert(reference_is_packed(ref) == 1);

	/* This should pass */
	cl_git_pass(git_reference_delete(ref));
	git_reference_free(ref);
}
Exemple #2
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);
}
Exemple #3
0
static void *create_refs(void *arg)
{
	int *id = arg, i;
	git_oid head;
	char name[128];
	git_reference *ref[10];

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

	for (i = 0; i < 10; ++i) {
		p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", *id, i);
		cl_git_pass(git_reference_create(&ref[i], g_repo, name, &head, 0, NULL));

		if (i == 5) {
			git_refdb *refdb;
			cl_git_pass(git_repository_refdb(&refdb, g_repo));
			cl_git_pass(git_refdb_compress(refdb));
			git_refdb_free(refdb);
		}
	}

	for (i = 0; i < 10; ++i)
		git_reference_free(ref[i]);

	giterr_clear();
	return arg;
}
int git_transaction_new(git_transaction **out, git_repository *repo)
{
	int error;
	git_pool pool;
	git_transaction *tx = NULL;

	assert(out && repo);

	if ((error = git_pool_init(&pool, 1, 0)) < 0)
		return error;

	tx = git_pool_mallocz(&pool, sizeof(git_transaction));
	if (!tx) {
		error = -1;
		goto on_error;
	}

	if ((error = git_strmap_alloc(&tx->locks)) < 0) {
		error = -1;
		goto on_error;
	}

	if ((error = git_repository_refdb(&tx->db, repo)) < 0)
		goto on_error;

	memcpy(&tx->pool, &pool, sizeof(git_pool));
	tx->repo = repo;
	*out = tx;
	return 0;

on_error:
	git_pool_clear(&pool);
	return error;
}
Exemple #5
0
static void *delete_refs(void *arg)
{
	int *id = arg, i;
	git_reference *ref;
	char name[128];

	for (i = 0; i < 10; ++i) {
		p_snprintf(
			name, sizeof(name), "refs/heads/thread-%03d-%02d", (*id) & ~0x3, i);

		if (!git_reference_lookup(&ref, g_repo, name)) {
			cl_git_pass(git_reference_delete(ref));
			git_reference_free(ref);
		}

		if (i == 5) {
			git_refdb *refdb;
			cl_git_pass(git_repository_refdb(&refdb, g_repo));
			cl_git_pass(git_refdb_compress(refdb));
			git_refdb_free(refdb);
		}
	}

	giterr_clear();
	return arg;
}
Exemple #6
0
static void packall(void)
{
	git_refdb *refdb;

	cl_git_pass(git_repository_refdb(&refdb, g_repo));
	cl_git_pass(git_refdb_compress(refdb));
	git_refdb_free(refdb);
}
Exemple #7
0
void test_threads_refdb__iterator(void)
{
	int r, t;
	git_thread th[THREADS];
	int id[THREADS];
	git_oid head;
	git_reference *ref;
	char name[128];
	git_refdb *refdb;

	g_repo = cl_git_sandbox_init("testrepo2");

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

	/* make a bunch of references */

	for (r = 0; r < 200; ++r) {
		p_snprintf(name, sizeof(name), "refs/heads/direct-%03d", r);
		cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
		git_reference_free(ref);
	}

	cl_git_pass(git_repository_refdb(&refdb, g_repo));
	cl_git_pass(git_refdb_compress(refdb));
	git_refdb_free(refdb);

	g_expected = 206;

	for (r = 0; r < REPEAT; ++r) {
		g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */

		for (t = 0; t < THREADS; ++t) {
			id[t] = t;
#ifdef GIT_THREADS
			cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t]));
#else
			th[t] = t;
			iterate_refs(&id[t]);
#endif
		}

#ifdef GIT_THREADS
		for (t = 0; t < THREADS; ++t) {
			cl_git_pass(git_thread_join(&th[t], NULL));
		}
#endif

		memset(th, 0, sizeof(th));
	}
}
Exemple #8
0
static void *create_refs(void *arg)
{
	int i, error;
	struct th_data *data = (struct th_data *) arg;
	git_oid head;
	char name[128];
	git_reference *ref[NREFS];
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));

	do {
		error = git_reference_name_to_id(&head, repo, "HEAD");
	} while (error == GIT_ELOCKED);
	cl_git_thread_pass(data, error);

	for (i = 0; i < NREFS; ++i) {
		p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", data->id, i);
		do {
			error = git_reference_create(&ref[i], repo, name, &head, 0, NULL);
		} while (error == GIT_ELOCKED);
		cl_git_thread_pass(data, error);

		if (concurrent_compress && i == NREFS/2) {
			git_refdb *refdb;
			cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
			do {
				error = git_refdb_compress(refdb);
			} while (error == GIT_ELOCKED);
			cl_git_thread_pass(data, error);
			git_refdb_free(refdb);
		}
	}

	for (i = 0; i < NREFS; ++i)
		git_reference_free(ref[i]);

	git_repository_free(repo);

	git_error_clear();
	return arg;
}
Exemple #9
0
static void *delete_refs(void *arg)
{
	int i, error;
	struct th_data *data = (struct th_data *) arg;
	git_reference *ref;
	char name[128];
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));

	for (i = 0; i < NREFS; ++i) {
		p_snprintf(
			name, sizeof(name), "refs/heads/thread-%03d-%02d", (data->id) & ~0x3, i);

		if (!git_reference_lookup(&ref, repo, name)) {
			do {
				error = git_reference_delete(ref);
			} while (error == GIT_ELOCKED);
			/* Sometimes we race with other deleter threads */
			if (error == GIT_ENOTFOUND)
				error = 0;

			cl_git_thread_pass(data, error);
			git_reference_free(ref);
		}

		if (concurrent_compress && i == NREFS/2) {
			git_refdb *refdb;
			cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
			do {
				error = git_refdb_compress(refdb);
			} while (error == GIT_ELOCKED);
			cl_git_thread_pass(data, error);
			git_refdb_free(refdb);
		}
	}

	git_repository_free(repo);
	git_error_clear();
	return arg;
}
Exemple #10
0
static void count_fsyncs(size_t *create_count, size_t *compress_count)
{
	git_reference *ref = NULL;
	git_refdb *refdb;
	git_oid id;

	p_fsync__cnt = 0;

	git_oid_fromstr(&id, current_master_tip);
	cl_git_pass(git_reference_create(&ref, g_repo, "refs/heads/fsync_test", &id, 0, "log message"));
	git_reference_free(ref);

	*create_count = p_fsync__cnt;
	p_fsync__cnt = 0;

	cl_git_pass(git_repository_refdb(&refdb, g_repo));
	cl_git_pass(git_refdb_compress(refdb));
	git_refdb_free(refdb);

	*compress_count = p_fsync__cnt;
	p_fsync__cnt = 0;
}
Exemple #11
0
void test_threads_refdb__edit_while_iterate(void)
{
	int r, t;
	int id[THREADS];
	git_oid head;
	git_reference *ref;
	char name[128];
	git_refdb *refdb;

#ifdef GIT_THREADS
	git_thread th[THREADS];
#endif

	g_repo = cl_git_sandbox_init("testrepo2");

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

	/* make a bunch of references */

	for (r = 0; r < 50; ++r) {
		p_snprintf(name, sizeof(name), "refs/heads/starter-%03d", r);
		cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
		git_reference_free(ref);
	}

	cl_git_pass(git_repository_refdb(&refdb, g_repo));
	cl_git_pass(git_refdb_compress(refdb));
	git_refdb_free(refdb);

	g_expected = -1;

	g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */

	for (t = 0; t < THREADS; ++t) {
		void *(*fn)(void *arg);

		switch (t & 0x3) {
		case 0:  fn = create_refs;  break;
		case 1:  fn = delete_refs;  break;
		default: fn = iterate_refs; break;
		}

		id[t] = t;

		/* It appears with all reflog writing changes, etc., that this
		 * test has started to fail quite frequently, so let's disable it
		 * for now by just running on a single thread...
		 */
/* #ifdef GIT_THREADS */
/*		cl_git_pass(git_thread_create(&th[t], fn, &id[t])); */
/* #else */
		fn(&id[t]);
/* #endif */
	}

#ifdef GIT_THREADS
/*	for (t = 0; t < THREADS; ++t) { */
/*		cl_git_pass(git_thread_join(th[t], NULL)); */
/*	} */

	memset(th, 0, sizeof(th));

	for (t = 0; t < THREADS; ++t) {
		id[t] = t;
		cl_git_pass(git_thread_create(&th[t], iterate_refs, &id[t]));
	}

	for (t = 0; t < THREADS; ++t) {
		cl_git_pass(git_thread_join(&th[t], NULL));
	}
#endif
}
Exemple #12
0
void test_threads_refdb__edit_while_iterate(void)
{
	int r, t;
	struct th_data th_data[THREADS];
	git_oid head;
	git_reference *ref;
	char name[128];
	git_refdb *refdb;

#ifdef GIT_THREADS
	git_thread th[THREADS];
#endif

	g_repo = cl_git_sandbox_init("testrepo2");

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

	/* make a bunch of references */

	for (r = 0; r < 50; ++r) {
		p_snprintf(name, sizeof(name), "refs/heads/starter-%03d", r);
		cl_git_pass(git_reference_create(&ref, g_repo, name, &head, 0, NULL));
		git_reference_free(ref);
	}

	cl_git_pass(git_repository_refdb(&refdb, g_repo));
	cl_git_pass(git_refdb_compress(refdb));
	git_refdb_free(refdb);

	g_expected = -1;

	g_repo = cl_git_sandbox_reopen(); /* reopen to flush caches */

	for (t = 0; t < THREADS; ++t) {
		void *(*fn)(void *arg);

		switch (t & 0x3) {
		case 0:  fn = create_refs;  break;
		case 1:  fn = delete_refs;  break;
		default: fn = iterate_refs; break;
		}

		th_data[t].id = t;
		th_data[t].path = git_repository_path(g_repo);

#ifdef GIT_THREADS
		cl_git_pass(git_thread_create(&th[t], fn, &th_data[t]));
#else
		fn(&th_data[t]);
#endif
	}

#ifdef GIT_THREADS
	for (t = 0; t < THREADS; ++t) {
		cl_git_pass(git_thread_join(&th[t], NULL));
		cl_git_thread_check(&th_data[t]);
	}

	memset(th, 0, sizeof(th));

	for (t = 0; t < THREADS; ++t) {
		th_data[t].id = t;
		cl_git_pass(git_thread_create(&th[t], iterate_refs, &th_data[t]));
	}

	for (t = 0; t < THREADS; ++t) {
		cl_git_pass(git_thread_join(&th[t], NULL));
		cl_git_thread_check(&th_data[t]);
	}
#endif
}