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 )