const char *git_attr__false = "[internal]__FALSE__";
const char *git_attr__unset = "[internal]__UNSET__";
-git_attr_t git_attr_value(const char *attr)
+git_attr_value_t git_attr_value(const char *attr)
{
if (attr == NULL || attr == git_attr__unset)
- return GIT_ATTR_UNSPECIFIED_T;
+ return GIT_ATTR_VALUE_UNSPECIFIED;
if (attr == git_attr__true)
- return GIT_ATTR_TRUE_T;
+ return GIT_ATTR_VALUE_TRUE;
if (attr == git_attr__false)
- return GIT_ATTR_FALSE_T;
+ return GIT_ATTR_VALUE_FALSE;
- return GIT_ATTR_VALUE_T;
+ return GIT_ATTR_VALUE_STRING;
}
static int collect_attr_files(
return -1;
if ((error = collect_attr_files(repo, NULL, flags, pathname, &files)) < 0 ||
- (error = git_strmap_alloc(&seen)) < 0)
+ (error = git_strmap_new(&seen)) < 0)
goto cleanup;
git_vector_foreach(&files, i, file) {
if (git_strmap_exists(seen, assign->name))
continue;
- git_strmap_insert(seen, assign->name, assign, &error);
- if (error < 0)
+ if ((error = git_strmap_set(seen, assign->name, assign)) < 0)
goto cleanup;
error = callback(assign->name, assign->value, payload);
git_attr_session *attr_session,
git_attr_file_source source,
const char *base,
- const char *file)
+ const char *file,
+ bool allow_macros)
{
int error;
git_attr_file *preload = NULL;
if (!file)
return 0;
- if (!(error = git_attr_cache__get(
- &preload, repo, attr_session, source, base, file, git_attr_file__parse_buffer)))
+ if (!(error = git_attr_cache__get(&preload, repo, attr_session, source, base, file,
+ git_attr_file__parse_buffer, allow_macros)))
git_attr_file__free(preload);
return error;
return 0;
}
-static int attr_setup(git_repository *repo, git_attr_session *attr_session)
+static int attr_setup(
+ git_repository *repo,
+ git_attr_session *attr_session,
+ uint32_t flags)
{
- int error = 0;
- const char *workdir = git_repository_workdir(repo);
- git_index *idx = NULL;
git_buf path = GIT_BUF_INIT;
+ git_index *idx = NULL;
+ const char *workdir;
+ int error = 0;
if (attr_session && attr_session->init_setup)
return 0;
if ((error = git_attr_cache__init(repo)) < 0)
return error;
- /* preload attribute files that could contain macros so the
- * definitions will be available for later file parsing
+ /*
+ * Preload attribute files that could contain macros so the
+ * definitions will be available for later file parsing.
*/
- error = system_attr_file(&path, attr_session);
-
- if (error == 0)
- error = preload_attr_file(
- repo, attr_session, GIT_ATTR_FILE__FROM_FILE, NULL, path.ptr);
-
- if (error != GIT_ENOTFOUND)
- goto out;
-
- if ((error = preload_attr_file(
- repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
- NULL, git_repository_attr_cache(repo)->cfg_attr_file)) < 0)
- goto out;
+ if ((error = system_attr_file(&path, attr_session)) < 0 ||
+ (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
+ NULL, path.ptr, true)) < 0) {
+ if (error != GIT_ENOTFOUND)
+ goto out;
+ }
- if ((error = git_repository_item_path(&path,
- repo, GIT_REPOSITORY_ITEM_INFO)) < 0)
+ if ((error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
+ NULL, git_repository_attr_cache(repo)->cfg_attr_file, true)) < 0)
goto out;
- if ((error = preload_attr_file(
- repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
- path.ptr, GIT_ATTR_FILE_INREPO)) < 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__FROM_FILE,
+ path.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) {
+ if (error != GIT_ENOTFOUND)
+ goto out;
+ }
- if (workdir != NULL &&
- (error = preload_attr_file(
- repo, attr_session, GIT_ATTR_FILE__FROM_FILE, workdir, GIT_ATTR_FILE)) < 0)
- goto out;
+ if ((workdir = git_repository_workdir(repo)) != NULL &&
+ (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_FILE,
+ workdir, GIT_ATTR_FILE, true)) < 0)
+ goto out;
if ((error = git_repository_index__weakptr(&idx, repo)) < 0 ||
- (error = preload_attr_file(
- repo, attr_session, GIT_ATTR_FILE__FROM_INDEX, NULL, GIT_ATTR_FILE)) < 0)
+ (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_INDEX,
+ NULL, GIT_ATTR_FILE, true)) < 0)
+ goto out;
+
+ if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0 &&
+ (error = preload_attr_file(repo, attr_session, GIT_ATTR_FILE__FROM_HEAD,
+ NULL, GIT_ATTR_FILE, true)) < 0)
goto out;
if (attr_session)
break;
}
+ if ((flags & GIT_ATTR_CHECK_INCLUDE_HEAD) != 0)
+ srcs[count++] = GIT_ATTR_FILE__FROM_HEAD;
+
return count;
}
git_vector *list,
git_attr_file_source source,
const char *base,
- const char *filename)
+ const char *filename,
+ bool allow_macros)
{
int error = 0;
git_attr_file *file = NULL;
error = git_attr_cache__get(&file, repo, attr_session,
- source, base, filename, git_attr_file__parse_buffer);
+ source, base, filename, git_attr_file__parse_buffer, allow_macros);
if (error < 0)
return error;
static int push_one_attr(void *ref, const char *path)
{
- int error = 0, n_src, i;
attr_walk_up_info *info = (attr_walk_up_info *)ref;
- git_attr_file_source src[2];
+ git_attr_file_source src[GIT_ATTR_FILE_NUM_SOURCES];
+ int error = 0, n_src, i;
+ bool allow_macros;
n_src = attr_decide_sources(
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);
+ error = push_attr_file(info->repo, info->attr_session, info->files,
+ src[i], path, GIT_ATTR_FILE, allow_macros);
return error;
}
const char *workdir = git_repository_workdir(repo);
attr_walk_up_info info = { NULL };
- if ((error = attr_setup(repo, attr_session)) < 0)
+ if ((error = attr_setup(repo, attr_session, flags)) < 0)
return error;
/* Resolve path in a non-bare repo */
* - $GIT_PREFIX/etc/gitattributes
*/
- error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO);
- if (error < 0)
- goto cleanup;
-
- error = push_attr_file(
- repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
- attrfile.ptr, GIT_ATTR_FILE_INREPO);
- if (error < 0)
- goto cleanup;
+ if ((error = git_repository_item_path(&attrfile, repo, GIT_REPOSITORY_ITEM_INFO)) < 0 ||
+ (error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
+ attrfile.ptr, GIT_ATTR_FILE_INREPO, true)) < 0) {
+ if (error != GIT_ENOTFOUND)
+ goto cleanup;
+ }
info.repo = repo;
info.attr_session = attr_session;
goto cleanup;
if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) {
- error = push_attr_file(
- repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
- NULL, git_repository_attr_cache(repo)->cfg_attr_file);
+ error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
+ NULL, git_repository_attr_cache(repo)->cfg_attr_file, true);
if (error < 0)
goto cleanup;
}
error = system_attr_file(&dir, attr_session);
if (!error)
- error = push_attr_file(
- repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
- NULL, dir.ptr);
+ error = push_attr_file(repo, attr_session, files, GIT_ATTR_FILE__FROM_FILE,
+ NULL, dir.ptr, true);
else if (error == GIT_ENOTFOUND)
error = 0;
}