Beispiel #1
0
int git_config_add_file(git_config *cfg, git_config_file *file, int priority)
{
	file_internal *internal;
	int error;

	assert(cfg && file);

	if ((error = file->open(file)) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to open config file");

	internal = git__malloc(sizeof(file_internal));
	if (internal == NULL)
		return GIT_ENOMEM;

	internal->file = file;
	internal->priority = priority;

	if (git_vector_insert(&cfg->files, internal) < 0) {
		free(internal);
		return GIT_ENOMEM;
	}

	git_vector_sort(&cfg->files);
	internal->file->cfg = cfg;

	return GIT_SUCCESS;
}
Beispiel #2
0
int git_fetchhead_write(git_repository *repo, git_vector *fetchhead_refs)
{
	git_filebuf file = GIT_FILEBUF_INIT;
	git_buf path = GIT_BUF_INIT;
	unsigned int i;
	git_fetchhead_ref *fetchhead_ref;

	assert(repo && fetchhead_refs);

	if (git_buf_joinpath(&path, repo->path_repository, GIT_FETCH_HEAD_FILE) < 0)
		return -1;

	if (git_filebuf_open(&file, path.ptr, GIT_FILEBUF_FORCE, GIT_REFS_FILE_MODE) < 0) {
		git_buf_free(&path);
		return -1;
	}

	git_buf_free(&path);

	git_vector_sort(fetchhead_refs);

	git_vector_foreach(fetchhead_refs, i, fetchhead_ref)
		fetchhead_ref_write(&file, fetchhead_ref);

	return git_filebuf_commit(&file);
}
Beispiel #3
0
int git_index_write(git_index *index)
{
	git_filebuf file;
	struct stat indexst;
	int error;

	git_vector_sort(&index->entries);

	if ((error = git_filebuf_open(&file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS)) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to write index");

	if ((error = write_index(index, &file)) < GIT_SUCCESS) {
		git_filebuf_cleanup(&file);
		return git__rethrow(error, "Failed to write index");
	}

	if ((error = git_filebuf_commit(&file)) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to write index");

	if (p_stat(index->index_file_path, &indexst) == 0) {
		index->last_modified = indexst.st_mtime;
		index->on_disk = 1;
	}

	return GIT_SUCCESS;
}
Beispiel #4
0
int git_tree_add_entry(git_tree_entry **entry_out, git_tree *tree, const git_oid *id, const char *filename, int attributes)
{
	git_tree_entry *entry;

	assert(tree && id && filename);

	if ((entry = git__malloc(sizeof(git_tree_entry))) == NULL)
		return GIT_ENOMEM;

	memset(entry, 0x0, sizeof(git_tree_entry));

	entry->filename = git__strdup(filename);
	git_oid_cpy(&entry->oid, id);
	entry->attr = attributes;
	entry->owner = tree;

	if (git_vector_insert(&tree->entries, entry) < 0)
		return GIT_ENOMEM;

	git_vector_sort(&tree->entries);

	if (entry_out != NULL)
		*entry_out = entry;

	tree->object.modified = 1;
	return GIT_SUCCESS;
}
Beispiel #5
0
int git_tree__writeback(git_tree *tree, git_odb_source *src)
{
	size_t i;
	char filemode[8];

	assert(tree && src);

	if (tree->entries.length == 0)
		return GIT_EMISSINGOBJDATA;

	git_vector_sort(&tree->entries);

	for (i = 0; i < tree->entries.length; ++i) {
		git_tree_entry *entry;

		entry = git_vector_get(&tree->entries, i);
	
		sprintf(filemode, "%06o ", entry->attr);

		git__source_write(src, filemode, strlen(filemode));
		git__source_write(src, entry->filename, strlen(entry->filename) + 1);
		git__source_write(src, entry->oid.id, GIT_OID_RAWSZ);
	} 

	return GIT_SUCCESS;
}
Beispiel #6
0
static int packfile_refresh_all(struct pack_backend *backend)
{
	int error;
	struct stat st;

	if (backend->pack_folder == NULL)
		return GIT_SUCCESS;

	if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
		return git__throw(GIT_ENOTFOUND, "Failed to refresh packfiles. Backend not found");

	if (st.st_mtime != backend->pack_folder_mtime) {
		char path[GIT_PATH_MAX];
		strcpy(path, backend->pack_folder);

		/* reload all packs */
		error = git_futils_direach(path, GIT_PATH_MAX, packfile_load__cb, (void *)backend);
		if (error < GIT_SUCCESS)
			return git__rethrow(error, "Failed to refresh packfiles");

		git_vector_sort(&backend->packs);
		backend->pack_folder_mtime = st.st_mtime;
	}

	return GIT_SUCCESS;
}
Beispiel #7
0
static int add_backend_internal(
	git_odb *odb, git_odb_backend *backend,
	int priority, bool is_alternate, ino_t disk_inode)
{
	backend_internal *internal;

	assert(odb && backend);

	GITERR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend");

	/* Check if the backend is already owned by another ODB */
	assert(!backend->odb || backend->odb == odb);

	internal = (backend_internal*) git__malloc(sizeof(backend_internal));
	GITERR_CHECK_ALLOC(internal);

	internal->backend = backend;
	internal->priority = priority;
	internal->is_alternate = is_alternate;
	internal->disk_inode = disk_inode;

	if (git_vector_insert(&odb->backends, internal) < 0) {
		git__free(internal);
		return -1;
	}

	git_vector_sort(&odb->backends);
	internal->backend->odb = odb;
	return 0;
}
Beispiel #8
0
static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int priority, int is_alternate)
{
	backend_internal *internal;

	assert(odb && backend);

	if (backend->odb != NULL && backend->odb != odb)
		return GIT_EBUSY;

	internal = git__malloc(sizeof(backend_internal));
	if (internal == NULL)
		return GIT_ENOMEM;

	internal->backend = backend;
	internal->priority = priority;
	internal->is_alternate = is_alternate;

	if (git_vector_insert(&odb->backends, internal) < 0) {
		free(internal);
		return GIT_ENOMEM;
	}

	git_vector_sort(&odb->backends);
	internal->backend->odb = odb;
	return GIT_SUCCESS;
}
Beispiel #9
0
void git_tree_entry_set_name(git_tree_entry *entry, const char *name)
{
	assert(entry && entry->owner);

	free(entry->filename);
	entry->filename = git__strdup(name);
	git_vector_sort(&entry->owner->entries);
	entry->owner->object.modified = 1;
}
Beispiel #10
0
static void assert_all_refnames_match(git_vector *output)
{
	size_t i;
	git_reference *ref;

	cl_assert_equal_sz(output->length, ARRAY_SIZE(refnames));

	git_vector_sort(output);

	git_vector_foreach(output, i, ref) {
		cl_assert_equal_s(ref->name, refnames[i]);
		git_reference_free(ref);
	}
Beispiel #11
0
int git_vector_bsearch2(git_vector *v, git_vector_cmp key_lookup, const void *key)
{
	void **find;

	assert(v && key && key_lookup);

	/* need comparison function to sort the vector */
	if (v->_cmp == NULL)
		return git__throw(GIT_ENOTFOUND, "Can't sort vector. No comparison function set");

	git_vector_sort(v);

	find = git__bsearch(key, v->contents, v->length, key_lookup);
	if (find != NULL)
		return (int)(find - v->contents);

	return git__throw(GIT_ENOTFOUND, "Can't find element");
}
Beispiel #12
0
void test_network_remote_rename__symref_head(void)
{
	int error;
	git_reference *ref;
	git_branch_t btype;
	git_branch_iterator *iter;
	git_strarray problems = {0};
	char idstr[GIT_OID_HEXSZ + 1] = {0};
	git_vector refs;

	cl_git_pass(git_reference_symbolic_create(&ref, _repo, "refs/remotes/test/HEAD", "refs/remotes/test/master", 0, NULL, NULL));
	git_reference_free(ref);

	cl_git_pass(git_remote_rename(&problems, _repo, _remote_name, "renamed"));
	cl_assert_equal_i(0, problems.count);
	git_strarray_free(&problems);

	cl_git_pass(git_vector_init(&refs, 2, (git_vector_cmp) git_reference_cmp));
	cl_git_pass(git_branch_iterator_new(&iter, _repo, GIT_BRANCH_REMOTE));

	while ((error = git_branch_next(&ref, &btype, iter)) == 0) {
		cl_git_pass(git_vector_insert(&refs, ref));
	}
	cl_assert_equal_i(GIT_ITEROVER, error);
	git_vector_sort(&refs);

	cl_assert_equal_i(2, refs.length);

	ref = git_vector_get(&refs, 0);
	cl_assert_equal_s("refs/remotes/renamed/HEAD", git_reference_name(ref));
	cl_assert_equal_s("refs/remotes/renamed/master", git_reference_symbolic_target(ref));
	git_reference_free(ref);

	ref = git_vector_get(&refs, 1);
	cl_assert_equal_s("refs/remotes/renamed/master", git_reference_name(ref));
	git_oid_fmt(idstr, git_reference_target(ref));
	cl_assert_equal_s("be3563ae3f795b2b4353bcce3a527ad0a4f7f644", idstr);
	git_reference_free(ref);

	git_vector_free(&refs);

	cl_git_fail_with(GIT_ITEROVER, git_branch_next(&ref, &btype, iter));
	git_branch_iterator_free(iter);
}
Beispiel #13
0
void git_vector_uniq(git_vector *v)
{
	git_vector_cmp cmp;
	unsigned int i, j;

	if (v->length <= 1)
		return;

	git_vector_sort(v);
	cmp = v->_cmp ? v->_cmp : strict_comparison;

	for (i = 0, j = 1 ; j < v->length; ++j)
		if (!cmp(v->contents[i], v->contents[j]))
			v->contents[i] = v->contents[j];
		else
			v->contents[++i] = v->contents[j];

	v->length -= j - i - 1;
}
Beispiel #14
0
/***********************************************************
 *
 * PACKED BACKEND PUBLIC API
 *
 * Implement the git_odb_backend API calls
 *
 ***********************************************************/
static int pack_backend__refresh(git_odb_backend *backend_)
{
	int error;
	struct stat st;
	git_buf path = GIT_BUF_INIT;
	struct pack_backend *backend = (struct pack_backend *)backend_;

	if (backend->pack_folder == NULL)
		return 0;

	if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
		return git_odb__error_notfound("failed to refresh packfiles", NULL);

	git_buf_sets(&path, backend->pack_folder);

	/* reload all packs */
	error = git_path_direach(&path, 0, packfile_load__cb, backend);

	git_buf_free(&path);
	git_vector_sort(&backend->packs);

	return error;
}
Beispiel #15
0
static void sort_entries(git_treebuilder *bld)
{
	git_vector_sort(&bld->entries);
}
Beispiel #16
0
int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats)
{
	git_mwindow *w = NULL;
	unsigned int i, long_offsets = 0, left;
	int error;
	struct git_pack_idx_header hdr;
	git_buf filename = GIT_BUF_INIT;
	struct entry *entry;
	git_oid trailer_hash, file_hash;
	git_hash_ctx ctx;
	git_filebuf index_file = {0};
	void *packfile_trailer;

	if (git_hash_ctx_init(&ctx) < 0)
		return -1;

	/* Test for this before resolve_deltas(), as it plays with idx->off */
	if (idx->off < idx->pack->mwf.size - 20) {
		giterr_set(GITERR_INDEXER, "Unexpected data at the end of the pack");
		return -1;
	}

	packfile_trailer = git_mwindow_open(&idx->pack->mwf, &w, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ, &left);
	if (packfile_trailer == NULL) {
		git_mwindow_close(&w);
		goto on_error;
	}

	/* Compare the packfile trailer as it was sent to us and what we calculated */
	git_oid_fromraw(&file_hash, (unsigned char*) packfile_trailer);
	git_mwindow_close(&w);

	git_hash_final(&trailer_hash, &idx->trailer);
	if (git_oid_cmp(&file_hash, &trailer_hash)) {
		giterr_set(GITERR_INDEXER, "packfile trailer mismatch");
		return -1;
	}

	/* Freeze the number of deltas */
	stats->total_deltas = stats->total_objects - stats->indexed_objects;

	if ((error = resolve_deltas(idx, stats)) < 0)
		return error;

	if (stats->indexed_objects != stats->total_objects) {
		giterr_set(GITERR_INDEXER, "early EOF");
		return -1;
	}

	if (stats->local_objects > 0) {
		if (update_header_and_rehash(idx, stats) < 0)
			return -1;

		git_hash_final(&trailer_hash, &idx->trailer);
		write_at(idx, &trailer_hash, idx->pack->mwf.size - GIT_OID_RAWSZ, GIT_OID_RAWSZ);
	}

	git_vector_sort(&idx->objects);

	git_buf_sets(&filename, idx->pack->pack_name);
	git_buf_shorten(&filename, strlen("pack"));
	git_buf_puts(&filename, "idx");
	if (git_buf_oom(&filename))
		return -1;

	if (git_filebuf_open(&index_file, filename.ptr,
		GIT_FILEBUF_HASH_CONTENTS, idx->mode) < 0)
		goto on_error;

	/* Write out the header */
	hdr.idx_signature = htonl(PACK_IDX_SIGNATURE);
	hdr.idx_version = htonl(2);
	git_filebuf_write(&index_file, &hdr, sizeof(hdr));

	/* Write out the fanout table */
	for (i = 0; i < 256; ++i) {
		uint32_t n = htonl(idx->fanout[i]);
		git_filebuf_write(&index_file, &n, sizeof(n));
	}

	/* Write out the object names (SHA-1 hashes) */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		git_filebuf_write(&index_file, &entry->oid, sizeof(git_oid));
		git_hash_update(&ctx, &entry->oid, GIT_OID_RAWSZ);
	}
	git_hash_final(&idx->hash, &ctx);

	/* Write out the CRC32 values */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		git_filebuf_write(&index_file, &entry->crc, sizeof(uint32_t));
	}

	/* Write out the offsets */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		uint32_t n;

		if (entry->offset == UINT32_MAX)
			n = htonl(0x80000000 | long_offsets++);
		else
			n = htonl(entry->offset);

		git_filebuf_write(&index_file, &n, sizeof(uint32_t));
	}

	/* Write out the long offsets */
	git_vector_foreach(&idx->objects, i, entry, struct entry*) {
		uint32_t split[2];

		if (entry->offset != UINT32_MAX)
			continue;

		split[0] = htonl(entry->offset_long >> 32);
		split[1] = htonl(entry->offset_long & 0xffffffff);

		git_filebuf_write(&index_file, &split, sizeof(uint32_t) * 2);
	}

	/* Write out the packfile trailer to the index */
	if (git_filebuf_write(&index_file, &trailer_hash, GIT_OID_RAWSZ) < 0)
		goto on_error;

	/* Write out the hash of the idx */
	if (git_filebuf_hash(&trailer_hash, &index_file) < 0)
		goto on_error;

	git_filebuf_write(&index_file, &trailer_hash, sizeof(git_oid));

	/* Figure out what the final name should be */
	if (index_path(&filename, idx, ".idx") < 0)
		goto on_error;

	/* Commit file */
	if (git_filebuf_commit_at(&index_file, filename.ptr) < 0)
		goto on_error;

	git_mwindow_free_all(&idx->pack->mwf);
	/* We need to close the descriptor here so Windows doesn't choke on commit_at */
	if (p_close(idx->pack->mwf.fd) < 0) {
		giterr_set(GITERR_OS, "failed to close packfile");
		goto on_error;
	}

	idx->pack->mwf.fd = -1;

	if (index_path(&filename, idx, ".pack") < 0)
		goto on_error;

	/* And don't forget to rename the packfile to its new place. */
	p_rename(idx->pack->pack_name, git_buf_cstr(&filename));

	git_buf_free(&filename);
	git_hash_ctx_cleanup(&ctx);
	return 0;

on_error:
	git_mwindow_free_all(&idx->pack->mwf);
	git_filebuf_cleanup(&index_file);
	git_buf_free(&filename);
	git_hash_ctx_cleanup(&ctx);
	return -1;
}
Beispiel #17
0
git_index_entry *git_index_get(git_index *index, unsigned int n)
{
	git_vector_sort(&index->entries);
	return git_vector_get(&index->entries, n);
}
Beispiel #18
0
int git_index_remove(git_index *index, int position)
{
	git_vector_sort(&index->entries);
	return git_vector_remove(&index->entries, (unsigned int)position);
}