Git-Raw

 view release on metacpan or  search on metacpan

deps/libgit2/src/libgit2/blob.c  view on Meta::CPAN

	mode_t hint_mode,
	bool try_load_filters)
{
	int error;
	struct stat st;
	git_odb *odb = NULL;
	git_object_size_t size;
	mode_t mode;
	git_str path = GIT_STR_INIT;

	GIT_ASSERT_ARG(hint_path || !try_load_filters);

	if (!content_path) {
		if (git_repository_workdir_path(&path, repo, hint_path) < 0)
			return -1;

		content_path = path.ptr;
	}

	if ((error = git_fs_path_lstat(content_path, &st)) < 0 ||
		(error = git_repository_odb(&odb, repo)) < 0)
		goto done;

	if (S_ISDIR(st.st_mode)) {
		git_error_set(GIT_ERROR_ODB, "cannot create blob from '%s': it is a directory", content_path);
		error = GIT_EDIRECTORY;
		goto done;
	}

	if (out_st)
		memcpy(out_st, &st, sizeof(st));

	size = st.st_size;
	mode = hint_mode ? hint_mode : st.st_mode;

	if (S_ISLNK(mode)) {
		error = write_symlink(id, odb, content_path, (size_t)size);
	} else {
		git_filter_list *fl = NULL;

		if (try_load_filters)
			/* Load the filters for writing this file to the ODB */
			error = git_filter_list_load(
				&fl, repo, NULL, hint_path,
				GIT_FILTER_TO_ODB, GIT_FILTER_DEFAULT);

		if (error < 0)
			/* well, that didn't work */;
		else if (fl == NULL)
			/* No filters need to be applied to the document: we can stream
			 * directly from disk */
			error = write_file_stream(id, odb, content_path, size);
		else {
			/* We need to apply one or more filters */
			error = write_file_filtered(id, &size, odb, content_path, fl, repo);

			git_filter_list_free(fl);
		}

		/*
		 * TODO: eventually support streaming filtered files, for files
		 * which are bigger than a given threshold. This is not a priority
		 * because applying a filter in streaming mode changes the final
		 * size of the blob, and without knowing its final size, the blob
		 * cannot be written in stream mode to the ODB.
		 *
		 * The plan is to do streaming writes to a tempfile on disk and then
		 * opening streaming that file to the ODB, using
		 * `write_file_stream`.
		 *
		 * CAREFULLY DESIGNED APIS YO
		 */
	}

done:
	git_odb_free(odb);
	git_str_dispose(&path);

	return error;
}

int git_blob_create_from_workdir(
	git_oid *id, git_repository *repo, const char *path)
{
	return git_blob__create_from_paths(id, NULL, repo, NULL, path, 0, true);
}

int git_blob_create_from_disk(
	git_oid *id, git_repository *repo, const char *path)
{
	int error;
	git_str full_path = GIT_STR_INIT;
	const char *workdir, *hintpath = NULL;

	if ((error = git_fs_path_prettify(&full_path, path, NULL)) < 0) {
		git_str_dispose(&full_path);
		return error;
	}

	workdir  = git_repository_workdir(repo);

	if (workdir && !git__prefixcmp(full_path.ptr, workdir))
		hintpath = full_path.ptr + strlen(workdir);

	error = git_blob__create_from_paths(
		id, NULL, repo, git_str_cstr(&full_path), hintpath, 0, !!hintpath);

	git_str_dispose(&full_path);
	return error;
}

typedef struct {
	git_writestream parent;
	git_filebuf fbuf;
	git_repository *repo;
	char *hintpath;
} blob_writestream;

static int blob_writestream_close(git_writestream *_stream)
{
	blob_writestream *stream = (blob_writestream *) _stream;

	git_filebuf_cleanup(&stream->fbuf);
	return 0;
}

static void blob_writestream_free(git_writestream *_stream)
{



( run in 0.759 second using v1.01-cache-2.11-cpan-0bb4e1dffa6 )