Git-Raw

 view release on metacpan or  search on metacpan

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

		if (p_stat(entry->fullpath, &st) < 0 ||
			S_ISDIR(st.st_mode) ||
			(fd = git_futils_open_ro(entry->fullpath)) < 0 ||
			(error = git_futils_readbuffer_fd(&content, fd, (size_t)st.st_size)) < 0)
			nonexistent = true;

		if (fd >= 0)
			p_close(fd);

		break;
	}
	case GIT_ATTR_FILE_SOURCE_HEAD:
	case GIT_ATTR_FILE_SOURCE_COMMIT: {
		if (source->type == GIT_ATTR_FILE_SOURCE_COMMIT) {
			if ((error = git_commit_lookup(&commit, repo, source->commit_id)) < 0 ||
			    (error = git_commit_tree(&tree, commit)) < 0)
				goto cleanup;
		} else {
			if ((error = git_repository_head_tree(&tree, repo)) < 0)
				goto cleanup;
		}

		if ((error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0) {
			/*
			 * If the attributes file does not exist, we can
			 * cache an empty file for this commit to prevent
			 * needless future lookups.
			 */
			if (error == GIT_ENOTFOUND) {
				error = 0;
				break;
			}

			goto cleanup;
		}

		if ((error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0)
			goto cleanup;

		/*
		 * Do not assume that data straight from the ODB is NULL-terminated;
		 * copy the contents of a file to a buffer to work on.
		 */
		blobsize = git_blob_rawsize(blob);

		GIT_ERROR_CHECK_BLOBSIZE(blobsize);
		if ((error = git_str_put(&content,
			git_blob_rawcontent(blob), (size_t)blobsize)) < 0)
			goto cleanup;

		break;
	}
	default:
		git_error_set(GIT_ERROR_INVALID, "unknown file source %d", source->type);
		return -1;
	}

	if ((error = git_attr_file__new(&file, entry, source)) < 0)
		goto cleanup;

	/* advance over a UTF8 BOM */
	content_str = git_str_cstr(&content);
	bom_offset = git_str_detect_bom(&bom, &content);

	if (bom == GIT_STR_BOM_UTF8)
		content_str += bom_offset;

	/* store the key of the attr_reader; don't bother with cache
	 * invalidation during the same attr reader session.
	 */
	if (attr_session)
		file->session_key = attr_session->key;

	if (parser && (error = parser(repo, file, content_str, allow_macros)) < 0) {
		git_attr_file__free(file);
		goto cleanup;
	}

	/* write cache breakers */
	if (nonexistent)
		file->nonexistent = 1;
	else if (source->type == GIT_ATTR_FILE_SOURCE_INDEX)
		git_oid_cpy(&file->cache_data.oid, git_blob_id(blob));
	else if (source->type == GIT_ATTR_FILE_SOURCE_HEAD)
		git_oid_cpy(&file->cache_data.oid, git_tree_id(tree));
	else if (source->type == GIT_ATTR_FILE_SOURCE_COMMIT)
		git_oid_cpy(&file->cache_data.oid, git_tree_id(tree));
	else if (source->type == GIT_ATTR_FILE_SOURCE_FILE)
		git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st);
	/* else always cacheable */

	*out = file;

cleanup:
	git_blob_free(blob);
	git_tree_entry_free(tree_entry);
	git_tree_free(tree);
	git_commit_free(commit);
	git_str_dispose(&content);

	return error;
}

int git_attr_file__out_of_date(
	git_repository *repo,
	git_attr_session *attr_session,
	git_attr_file *file,
	git_attr_file_source *source)
{
	if (!file)
		return 1;

	/* we are never out of date if we just created this data in the same
	 * attr_session; otherwise, nonexistent files must be invalidated
	 */
	if (attr_session && attr_session->key == file->session_key)
		return 0;
	else if (file->nonexistent)
		return 1;

	switch (file->source.type) {
	case GIT_ATTR_FILE_SOURCE_MEMORY:
		return 0;

	case GIT_ATTR_FILE_SOURCE_FILE:



( run in 2.585 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )