diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2021-05-24 13:44:45 +0100 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2021-07-22 15:08:50 -0400 |
commit | 1cd863fd16a60517d2e42402c69238bf03b5dae0 (patch) | |
tree | e7f7c790286f29b284caa53c890b60879a9a458d | |
parent | 96dc1ffdc864c883e632989d75c32f602b107c83 (diff) | |
download | libgit2-1cd863fd16a60517d2e42402c69238bf03b5dae0.tar.gz |
attr: include the filename in the attr source
The attribute source object is now the type and the path.
-rw-r--r-- | src/attr.c | 109 | ||||
-rw-r--r-- | src/attr_file.c | 6 | ||||
-rw-r--r-- | src/attr_file.h | 10 | ||||
-rw-r--r-- | src/attrcache.c | 39 | ||||
-rw-r--r-- | src/attrcache.h | 6 | ||||
-rw-r--r-- | src/ignore.c | 12 |
6 files changed, 104 insertions, 78 deletions
diff --git a/src/attr.c b/src/attr.c index a8848ca6c..86be08474 100644 --- a/src/attr.c +++ b/src/attr.c @@ -253,28 +253,43 @@ cleanup: return error; } -static int preload_attr_file( +static int preload_attr_source( git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *file, - bool allow_macros) + git_attr_file_source *source) { int error; git_attr_file *preload = NULL; - if (!file) + if (!source) return 0; - if (!(error = git_attr_cache__get(&preload, repo, attr_session, - source_type, base, file, - git_attr_file__parse_buffer, - allow_macros))) + + error = git_attr_cache__get(&preload, repo, attr_session, source, + git_attr_file__parse_buffer, true); + + if (!error) git_attr_file__free(preload); 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( git_buf *out, git_attr_session *attr_session) @@ -318,7 +333,9 @@ static int attr_setup( git_attr_session *attr_session, 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; const char *workdir; int error = 0; @@ -334,45 +351,44 @@ static int attr_setup( * definitions will be available for later file parsing. */ - if ((error = system_attr_file(&path, attr_session)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - NULL, path.ptr, true)) < 0) { + if ((error = system_attr_file(&system, attr_session)) < 0 || + (error = preload_attr_file(repo, attr_session, NULL, system.ptr)) < 0) { if (error != GIT_ENOTFOUND) goto out; + + error = 0; } - if ((error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - NULL, git_repository_attr_cache(repo)->cfg_attr_file, true)) < 0) + if ((error = preload_attr_file(repo, attr_session, NULL, + git_repository_attr_cache(repo)->cfg_attr_file)) < 0) 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(&path, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - path.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) { + if ((error = git_repository_item_path(&info, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 || + (error = preload_attr_file(repo, attr_session, info.ptr, GIT_ATTR_FILE_INREPO)) < 0) { if (error != GIT_ENOTFOUND) goto out; + + error = 0; } if ((workdir = git_repository_workdir(repo)) != NULL && - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_FILE, - workdir, GIT_ATTR_FILE, true)) < 0) + (error = preload_attr_file(repo, attr_session, workdir, GIT_ATTR_FILE)) < 0) goto out; if ((error = git_repository_index__weakptr(&idx, repo)) < 0 || - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_INDEX, - NULL, GIT_ATTR_FILE, true)) < 0) + (error = preload_attr_source(repo, attr_session, &index_source)) < 0) goto out; if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 && - (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE_SOURCE_HEAD, - NULL, GIT_ATTR_FILE, true)) < 0) + (error = preload_attr_source(repo, attr_session, &head_source)) < 0) goto out; if (attr_session) attr_session->init_setup = 1; out: - git_buf_dispose(&path); + git_buf_dispose(&system); + git_buf_dispose(&info); return error; } @@ -451,25 +467,23 @@ static int attr_decide_sources( } if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0) - srcs[count++] = GIT_ATTR_FILE_SOURCE_HEAD; + srcs[count++] = GIT_ATTR_FILE_SOURCE_COMMIT; return count; } -static int push_attr_file( +static int push_attr_source( git_repository *repo, git_attr_session *attr_session, git_vector *list, - git_attr_file_source_t source_type, - const char *base, - const char *filename, + git_attr_file_source *source, bool allow_macros) { int error = 0; git_attr_file *file = NULL; error = git_attr_cache__get(&file, repo, attr_session, - source_type, base, filename, + source, git_attr_file__parse_buffer, allow_macros); @@ -484,6 +498,17 @@ static int push_attr_file( 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) { attr_walk_up_info *info = (attr_walk_up_info *)ref; @@ -495,9 +520,12 @@ static int push_one_attr(void *ref, const char *path) info->flags, info->workdir != NULL, info->index != NULL, src); allow_macros = info->workdir ? !strcmp(info->workdir, path) : false; - for (i = 0; !error && i < n_src; ++i) - error = push_attr_file(info->repo, info->attr_session, info->files, - src[i], path, GIT_ATTR_FILE, allow_macros); + for (i = 0; !error && i < n_src; ++i) { + git_attr_file_source source = { src[i], path, GIT_ATTR_FILE }; + + error = push_attr_source(info->repo, info->attr_session, info->files, + &source, allow_macros); + } return error; } @@ -549,8 +577,7 @@ static int collect_attr_files( */ 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, - attrfile.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) { + (error = push_attr_file(repo, attr_session, files, attrfile.ptr, GIT_ATTR_FILE_INREPO)) < 0) { if (error != GIT_ENOTFOUND) goto cleanup; } @@ -572,8 +599,7 @@ static int collect_attr_files( goto cleanup; if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) { - error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, - NULL, git_repository_attr_cache(repo)->cfg_attr_file, true); + error = push_attr_file(repo, attr_session, files, NULL, git_repository_attr_cache(repo)->cfg_attr_file); if (error < 0) goto cleanup; } @@ -582,8 +608,7 @@ static int collect_attr_files( error = system_attr_file(&dir, attr_session); if (!error) - error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE_SOURCE_FILE, - NULL, dir.ptr, true); + error = push_attr_file(repo, attr_session, files, NULL, dir.ptr); else if (error == GIT_ENOTFOUND) error = 0; } diff --git a/src/attr_file.c b/src/attr_file.c index db16a4793..b5860238c 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -162,7 +162,7 @@ int git_attr_file__load( break; } - case GIT_ATTR_FILE_SOURCE_HEAD: { + case GIT_ATTR_FILE_SOURCE_COMMIT: { if ((error = git_repository_head_tree(&tree, repo)) < 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) @@ -212,7 +212,7 @@ int git_attr_file__load( 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) + 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); @@ -264,7 +264,7 @@ int git_attr_file__out_of_date( 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; int error; diff --git a/src/attr_file.h b/src/attr_file.h index 6f5318d05..691dbda9e 100644 --- a/src/attr_file.h +++ b/src/attr_file.h @@ -40,13 +40,21 @@ typedef enum { GIT_ATTR_FILE_SOURCE_MEMORY = 0, GIT_ATTR_FILE_SOURCE_FILE = 1, 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_source_t; typedef struct { + /* The source location for the attribute file. */ 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; extern const char *git_attr__true; diff --git a/src/attrcache.c b/src/attrcache.c index 1f842c6e2..f07712735 100644 --- a/src/attrcache.c +++ b/src/attrcache.c @@ -158,41 +158,42 @@ static int attr_cache_lookup( git_attr_file_entry **out_entry, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *filename) + git_attr_file_source *source) { int error = 0; 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_file_entry *entry = NULL; git_attr_file *file = NULL; /* 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; - 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) return -1; filename = p->ptr; + } else { + filename = source->filename; } - relfile = filename; - if (wd && !git__prefixcmp(relfile, wd)) - relfile += strlen(wd); + if (wd && !git__prefixcmp(filename, wd)) + filename += strlen(wd); /* check cache for existing entry */ if ((error = attr_cache_lock(cache)) < 0) goto cleanup; - entry = attr_cache_lookup_entry(cache, relfile); - if (!entry) - error = attr_cache_make_entry(&entry, repo, relfile); - else if (entry->file[source_type] != NULL) { - file = entry->file[source_type]; + entry = attr_cache_lookup_entry(cache, filename); + + if (!entry) { + error = attr_cache_make_entry(&entry, repo, filename); + } else if (entry->file[source->type] != NULL) { + file = entry->file[source->type]; GIT_REFCOUNT_INC(file); } @@ -210,9 +211,7 @@ int git_attr_cache__get( git_attr_file **out, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *filename, + git_attr_file_source *source, git_attr_file_parser parser, bool allow_macros) { @@ -220,16 +219,14 @@ int git_attr_cache__get( git_attr_cache *cache = git_repository_attr_cache(repo); git_attr_file_entry *entry = 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, - source_type, base, filename)) < 0) + if ((error = attr_cache_lookup(&file, &entry, repo, attr_session, source)) < 0) return error; /* 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) error = git_attr_file__load(&updated, repo, attr_session, - entry, &source, parser, + entry, source, parser, allow_macros); /* if we loaded the file, insert into and/or update cache */ diff --git a/src/attrcache.h b/src/attrcache.h index 6d1d968a7..b13e0e8f0 100644 --- a/src/attrcache.h +++ b/src/attrcache.h @@ -31,16 +31,14 @@ extern int git_attr_cache__get( git_attr_file **file, git_repository *repo, git_attr_session *attr_session, - git_attr_file_source_t source_type, - const char *base, - const char *filename, + git_attr_file_source *source, git_attr_file_parser parser, bool allow_macros); extern bool git_attr_cache__is_cached( git_repository *repo, git_attr_file_source_t source_type, - const char *path); + const char *filename); extern int git_attr_cache__alloc_file_entry( git_attr_file_entry **out, diff --git a/src/ignore.c b/src/ignore.c index db342898d..f7551cddb 100644 --- a/src/ignore.c +++ b/src/ignore.c @@ -247,12 +247,11 @@ static int push_ignore_file( const char *base, const char *filename) { - int error = 0; + git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_FILE, base, filename }; git_attr_file *file = NULL; + int error = 0; - error = git_attr_cache__get(&file, ignores->repo, NULL, - GIT_ATTR_FILE_SOURCE_FILE, base, - filename, parse_ignore_file, false); + error = git_attr_cache__get(&file, ignores->repo, NULL, &source, parse_ignore_file, false); if (error < 0) return error; @@ -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) { + git_attr_file_source source = { GIT_ATTR_FILE_SOURCE_MEMORY, NULL, GIT_IGNORE_INTERNAL }; int error; if ((error = git_attr_cache__init(repo)) < 0) return error; - error = git_attr_cache__get(out, repo, NULL, - GIT_ATTR_FILE_SOURCE_MEMORY, NULL, - GIT_IGNORE_INTERNAL, NULL, false); + error = git_attr_cache__get(out, repo, NULL, &source, NULL, false); /* if internal rules list is empty, insert default rules */ if (!error && !(*out)->rules.length) |