Commit 1cd863fd by Edward Thomson

attr: include the filename in the attr source

The attribute source object is now the type and the path.
parent 96dc1ffd
...@@ -253,28 +253,43 @@ cleanup: ...@@ -253,28 +253,43 @@ cleanup:
return error; return error;
} }
static int preload_attr_file( static int preload_attr_source(
git_repository *repo, git_repository *repo,
git_attr_session *attr_session, git_attr_session *attr_session,
git_attr_file_source_t source_type, git_attr_file_source *source)
const char *base,
const char *file,
bool allow_macros)
{ {
int error; int error;
git_attr_file *preload = NULL; git_attr_file *preload = NULL;
if (!file) if (!source)
return 0; return 0;
if (!(error = git_attr_cache__get(&preload, repo, attr_session,
source_type, base, file, error = git_attr_cache__get(&preload, repo, attr_session, source,
git_attr_file__parse_buffer, git_attr_file__parse_buffer, true);
allow_macros)))
if (!error)
git_attr_file__free(preload); git_attr_file__free(preload);
return error; return error;
} }
GIT_INLINE(int) preload_attr_file(
git_repository *repo,
git_attr_session *attr_session,
const char *base,
const char *filename)
{
git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE };
if (!filename)
return 0;
source.base = base;
source.filename = filename;
return preload_attr_source(repo, attr_session, &source);
}
static int system_attr_file( static int system_attr_file(
git_buf *out, git_buf *out,
git_attr_session *attr_session) git_attr_session *attr_session)
...@@ -318,7 +333,9 @@ static int attr_setup( ...@@ -318,7 +333,9 @@ static int attr_setup(
git_attr_session *attr_session, git_attr_session *attr_session,
uint32_t flags) uint32_t flags)
{ {
git_buf path = GIT_BUF_INIT; git_buf system = GIT_BUF_INIT, info = GIT_BUF_INIT;
git_attr_file_source index_source = { GIT_ATTR_FILE_SOURCE_INDEX, NULL, GIT_ATTR_FILE };
git_attr_file_source head_source = { GIT_ATTR_FILE_SOURCE_COMMIT, NULL, GIT_ATTR_FILE };
git_index *idx = NULL; git_index *idx = NULL;
const char *workdir; const char *workdir;
int error = 0; int error = 0;
...@@ -334,45 +351,44 @@ static int attr_setup( ...@@ -334,45 +351,44 @@ static int attr_setup(
* definitions will be available for later file parsing. * definitions will be available for later file parsing.
*/ */
if ((error = system_attr_file(&path, attr_session)) < 0 || if ((error = system_attr_file(&system, attr_session)) < 0 ||
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, (error = preload_attr_file(repo, attr_session, NULL, system.ptr)) < 0) {
NULL, path.ptr, true)) < 0) {
if (error != GIT_ENOTFOUND) if (error != GIT_ENOTFOUND)
goto out; goto out;
error = 0;
} }
if ((error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, if ((error = preload_attr_file(repo, attr_session, NULL,
NULL, git_repository_attr_cache(repo)->cfg_attr_file, true)) < 0) git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
goto out; goto out;
git_buf_clear(&path); /* git_repository_item_path expects an empty buffer, because it uses git_buf_set */ if ((error = git_repository_item_path(&info, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 ||
if ((error = git_repository_item_path(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || (error = preload_attr_file(repo, attr_session, info.ptr, GIT_ATTR_FILE_INREPO)) < 0) {
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE,
path.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) {
if (error != GIT_ENOTFOUND) if (error != GIT_ENOTFOUND)
goto out; goto out;
error = 0;
} }
if ((workdir = git_repository_workdir(repo)) != NULL && if ((workdir = git_repository_workdir(repo)) != NULL &&
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, (error = preload_attr_file(repo, attr_session, workdir, GIT_ATTR_FILE)) < 0)
workdir, GIT_ATTR_FILE, true)) < 0)
goto out; goto out;
if ((error = git_repository_index__weakptr(&idx, repo)) < 0 || if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_INDEX, (error = preload_attr_source(repo, attr_session, &index_source)) < 0)
NULL, GIT_ATTR_FILE, true)) < 0)
goto out; goto out;
if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 && if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 &&
(error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_HEAD, (error = preload_attr_source(repo, attr_session, &head_source)) < 0)
NULL, GIT_ATTR_FILE, true)) < 0)
goto out; goto out;
if (attr_session) if (attr_session)
attr_session->init_setup = 1; attr_session->init_setup = 1;
out: out:
git_buf_dispose(&path); git_buf_dispose(&system);
git_buf_dispose(&info);
return error; return error;
} }
...@@ -451,25 +467,23 @@ static int attr_decide_sources( ...@@ -451,25 +467,23 @@ static int attr_decide_sources(
} }
if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0)
srcs[count++] = GIT_ATTR_FILE_SOURCE_HEAD; srcs[count++] = GIT_ATTR_FILE_SOURCE_COMMIT;
return count; return count;
} }
static int push_attr_file( static int push_attr_source(
git_repository *repo, git_repository *repo,
git_attr_session *attr_session, git_attr_session *attr_session,
git_vector *list, git_vector *list,
git_attr_file_source_t source_type, git_attr_file_source *source,
const char *base,
const char *filename,
bool allow_macros) bool allow_macros)
{ {
int error = 0; int error = 0;
git_attr_file *file = NULL; git_attr_file *file = NULL;
error = git_attr_cache__get(&file, repo, attr_session, error = git_attr_cache__get(&file, repo, attr_session,
source_type, base, filename, source,
git_attr_file__parse_buffer, git_attr_file__parse_buffer,
allow_macros); allow_macros);
...@@ -484,6 +498,17 @@ static int push_attr_file( ...@@ -484,6 +498,17 @@ static int push_attr_file(
return error; return error;
} }
GIT_INLINE(int) push_attr_file(
git_repository *repo,
git_attr_session *attr_session,
git_vector *list,
const char *base,
const char *filename)
{
git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE, base, filename };
return push_attr_source(repo, attr_session, list, &source, true);
}
static int push_one_attr(void *ref, const char *path) static int push_one_attr(void *ref, const char *path)
{ {
attr_walk_up_info *info = (attr_walk_up_info *)ref; attr_walk_up_info *info = (attr_walk_up_info *)ref;
...@@ -495,9 +520,12 @@ static int push_one_attr(void *ref, const char *path) ...@@ -495,9 +520,12 @@ static int push_one_attr(void *ref, const char *path)
info->flags, info->workdir != NULL, info->index != NULL, src); info->flags, info->workdir != NULL, info->index != NULL, src);
allow_macros = info->workdir ? !strcmp(info->workdir, path) : false; allow_macros = info->workdir ? !strcmp(info->workdir, path) : false;
for (i = 0; !error && i < n_src; ++i) for (i = 0; !error && i < n_src; ++i) {
error = push_attr_file(info->repo, info->attr_session, info->files, git_attr_file_source source = { src[i], path, GIT_ATTR_FILE };
src[i], path, GIT_ATTR_FILE, allow_macros);
error = push_attr_source(info->repo, info->attr_session, info->files,
&source, allow_macros);
}
return error; return error;
} }
...@@ -549,8 +577,7 @@ static int collect_attr_files( ...@@ -549,8 +577,7 @@ static int collect_attr_files(
*/ */
if ((error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || if ((error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 ||
(error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, (error = push_attr_file(repo, attr_session, files, attrfile.ptr, GIT_ATTR_FILE_INREPO)) < 0) {
attrfile.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) {
if (error != GIT_ENOTFOUND) if (error != GIT_ENOTFOUND)
goto cleanup; goto cleanup;
} }
...@@ -572,8 +599,7 @@ static int collect_attr_files( ...@@ -572,8 +599,7 @@ static int collect_attr_files(
goto cleanup; goto cleanup;
if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) { if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) {
error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, error = push_attr_file(repo, attr_session, files, NULL, git_repository_attr_cache(repo)->cfg_attr_file);
NULL, git_repository_attr_cache(repo)->cfg_attr_file, true);
if (error < 0) if (error < 0)
goto cleanup; goto cleanup;
} }
...@@ -582,8 +608,7 @@ static int collect_attr_files( ...@@ -582,8 +608,7 @@ static int collect_attr_files(
error = system_attr_file(&dir, attr_session); error = system_attr_file(&dir, attr_session);
if (!error) if (!error)
error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, error = push_attr_file(repo, attr_session, files, NULL, dir.ptr);
NULL, dir.ptr, true);
else if (error == GIT_ENOTFOUND) else if (error == GIT_ENOTFOUND)
error = 0; error = 0;
} }
......
...@@ -162,7 +162,7 @@ int git_attr_file__load( ...@@ -162,7 +162,7 @@ int git_attr_file__load(
break; break;
} }
case GIT_ATTR_FILE_SOURCE_HEAD: { case GIT_ATTR_FILE_SOURCE_COMMIT: {
if ((error = git_repository_head_tree(&tree, repo)) < 0 || if ((error = git_repository_head_tree(&tree, repo)) < 0 ||
(error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0 || (error = git_tree_entry_bypath(&tree_entry, tree, entry->path)) < 0 ||
(error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0) (error = git_blob_lookup(&blob, repo, git_tree_entry_id(tree_entry))) < 0)
...@@ -212,7 +212,7 @@ int git_attr_file__load( ...@@ -212,7 +212,7 @@ int git_attr_file__load(
file->nonexistent = 1; file->nonexistent = 1;
else if (source->type == GIT_ATTR_FILE_SOURCE_INDEX) else if (source->type == GIT_ATTR_FILE_SOURCE_INDEX)
git_oid_cpy(&file->cache_data.oid, git_blob_id(blob)); git_oid_cpy(&file->cache_data.oid, git_blob_id(blob));
else if (source->type == GIT_ATTR_FILE_SOURCE_HEAD) else if (source->type == GIT_ATTR_FILE_SOURCE_COMMIT)
git_oid_cpy(&file->cache_data.oid, git_tree_id(tree)); git_oid_cpy(&file->cache_data.oid, git_tree_id(tree));
else if (source->type == GIT_ATTR_FILE_SOURCE_FILE) else if (source->type == GIT_ATTR_FILE_SOURCE_FILE)
git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st); git_futils_filestamp_set_from_stat(&file->cache_data.stamp, &st);
...@@ -264,7 +264,7 @@ int git_attr_file__out_of_date( ...@@ -264,7 +264,7 @@ int git_attr_file__out_of_date(
return (git_oid__cmp(&file->cache_data.oid, &id) != 0); return (git_oid__cmp(&file->cache_data.oid, &id) != 0);
} }
case GIT_ATTR_FILE_SOURCE_HEAD: { case GIT_ATTR_FILE_SOURCE_COMMIT: {
git_tree *tree; git_tree *tree;
int error; int error;
......
...@@ -40,13 +40,21 @@ typedef enum { ...@@ -40,13 +40,21 @@ typedef enum {
GIT_ATTR_FILE_SOURCE_MEMORY = 0, GIT_ATTR_FILE_SOURCE_MEMORY = 0,
GIT_ATTR_FILE_SOURCE_FILE = 1, GIT_ATTR_FILE_SOURCE_FILE = 1,
GIT_ATTR_FILE_SOURCE_INDEX = 2, GIT_ATTR_FILE_SOURCE_INDEX = 2,
GIT_ATTR_FILE_SOURCE_HEAD = 3, GIT_ATTR_FILE_SOURCE_COMMIT = 3,
GIT_ATTR_FILE_NUM_SOURCES = 4 GIT_ATTR_FILE_NUM_SOURCES = 4
} git_attr_file_source_t; } git_attr_file_source_t;
typedef struct { typedef struct {
/* The source location for the attribute file. */
git_attr_file_source_t type; git_attr_file_source_t type;
/*
* The filename of the attribute file to read (relative to the
* given base path).
*/
const char *base;
const char *filename;
} git_attr_file_source; } git_attr_file_source;
extern const char *git_attr__true; extern const char *git_attr__true;
......
...@@ -158,41 +158,42 @@ static int attr_cache_lookup( ...@@ -158,41 +158,42 @@ static int attr_cache_lookup(
git_attr_file_entry **out_entry, git_attr_file_entry **out_entry,
git_repository *repo, git_repository *repo,
git_attr_session *attr_session, git_attr_session *attr_session,
git_attr_file_source_t source_type, git_attr_file_source *source)
const char *base,
const char *filename)
{ {
int error = 0; int error = 0;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
const char *wd = git_repository_workdir(repo), *relfile; const char *wd = git_repository_workdir(repo);
const char *filename;
git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_cache *cache = git_repository_attr_cache(repo);
git_attr_file_entry *entry = NULL; git_attr_file_entry *entry = NULL;
git_attr_file *file = NULL; git_attr_file *file = NULL;
/* join base and path as needed */ /* join base and path as needed */
if (base != NULL && git_path_root(filename) < 0) { if (source->base != NULL && git_path_root(source->filename) < 0) {
git_buf *p = attr_session ? &attr_session->tmp : &path; git_buf *p = attr_session ? &attr_session->tmp : &path;
if (git_buf_joinpath(p, base, filename) < 0 || if (git_buf_joinpath(p, source->base, source->filename) < 0 ||
git_path_validate_workdir_buf(repo, p) < 0) git_path_validate_workdir_buf(repo, p) < 0)
return -1; return -1;
filename = p->ptr; filename = p->ptr;
} else {
filename = source->filename;
} }
relfile = filename; if (wd && !git__prefixcmp(filename, wd))
if (wd && !git__prefixcmp(relfile, wd)) filename += strlen(wd);
relfile += strlen(wd);
/* check cache for existing entry */ /* check cache for existing entry */
if ((error = attr_cache_lock(cache)) < 0) if ((error = attr_cache_lock(cache)) < 0)
goto cleanup; goto cleanup;
entry = attr_cache_lookup_entry(cache, relfile); entry = attr_cache_lookup_entry(cache, filename);
if (!entry)
error = attr_cache_make_entry(&entry, repo, relfile); if (!entry) {
else if (entry->file[source_type] != NULL) { error = attr_cache_make_entry(&entry, repo, filename);
file = entry->file[source_type]; } else if (entry->file[source->type] != NULL) {
file = entry->file[source->type];
GIT_REFCOUNT_INC(file); GIT_REFCOUNT_INC(file);
} }
...@@ -210,9 +211,7 @@ int git_attr_cache__get( ...@@ -210,9 +211,7 @@ int git_attr_cache__get(
git_attr_file **out, git_attr_file **out,
git_repository *repo, git_repository *repo,
git_attr_session *attr_session, git_attr_session *attr_session,
git_attr_file_source_t source_type, git_attr_file_source *source,
const char *base,
const char *filename,
git_attr_file_parser parser, git_attr_file_parser parser,
bool allow_macros) bool allow_macros)
{ {
...@@ -220,16 +219,14 @@ int git_attr_cache__get( ...@@ -220,16 +219,14 @@ int git_attr_cache__get(
git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_cache *cache = git_repository_attr_cache(repo);
git_attr_file_entry *entry = NULL; git_attr_file_entry *entry = NULL;
git_attr_file *file = NULL, *updated = NULL; git_attr_file *file = NULL, *updated = NULL;
git_attr_file_source source = { source_type };
if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, source)) < 0)
source_type, base, filename)) < 0)
return error; return error;
/* load file if we don't have one or if existing one is out of date */ /* load file if we don't have one or if existing one is out of date */
if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0) if (!file || (error = git_attr_file__out_of_date(repo, attr_session, file)) > 0)
error = git_attr_file__load(&updated, repo, attr_session, error = git_attr_file__load(&updated, repo, attr_session,
entry, &source, parser, entry, source, parser,
allow_macros); allow_macros);
/* if we loaded the file, insert into and/or update cache */ /* if we loaded the file, insert into and/or update cache */
......
...@@ -31,16 +31,14 @@ extern int git_attr_cache__get( ...@@ -31,16 +31,14 @@ extern int git_attr_cache__get(
git_attr_file **file, git_attr_file **file,
git_repository *repo, git_repository *repo,
git_attr_session *attr_session, git_attr_session *attr_session,
git_attr_file_source_t source_type, git_attr_file_source *source,
const char *base,
const char *filename,
git_attr_file_parser parser, git_attr_file_parser parser,
bool allow_macros); bool allow_macros);
extern bool git_attr_cache__is_cached( extern bool git_attr_cache__is_cached(
git_repository *repo, git_repository *repo,
git_attr_file_source_t source_type, git_attr_file_source_t source_type,
const char *path); const char *filename);
extern int git_attr_cache__alloc_file_entry( extern int git_attr_cache__alloc_file_entry(
git_attr_file_entry **out, git_attr_file_entry **out,
......
...@@ -247,12 +247,11 @@ static int push_ignore_file( ...@@ -247,12 +247,11 @@ static int push_ignore_file(
const char *base, const char *base,
const char *filename) const char *filename)
{ {
int error = 0; git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE, base, filename };
git_attr_file *file = NULL; git_attr_file *file = NULL;
int error = 0;
error = git_attr_cache__get(&file, ignores->repo, NULL, error = git_attr_cache__get(&file, ignores->repo, NULL, &source, parse_ignore_file, false);
GIT_ATTR_FILE_SOURCE_FILE, base,
filename, parse_ignore_file, false);
if (error < 0) if (error < 0)
return error; return error;
...@@ -274,14 +273,13 @@ static int push_one_ignore(void *payload, const char *path) ...@@ -274,14 +273,13 @@ static int push_one_ignore(void *payload, const char *path)
static int get_internal_ignores(git_attr_file **out, git_repository *repo) static int get_internal_ignores(git_attr_file **out, git_repository *repo)
{ {
git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_MEMORY, NULL, GIT_IGNORE_INTERNAL };
int error; int error;
if ((error = git_attr_cache__init(repo)) < 0) if ((error = git_attr_cache__init(repo)) < 0)
return error; return error;
error = git_attr_cache__get(out, repo, NULL, error = git_attr_cache__get(out, repo, NULL, &source, NULL, false);
GIT_ATTR_FILE_SOURCE_MEMORY, NULL,
GIT_IGNORE_INTERNAL, NULL, false);
/* if internal rules list is empty, insert default rules */ /* if internal rules list is empty, insert default rules */
if (!error && !(*out)->rules.length) if (!error && !(*out)->rules.length)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment