summaryrefslogtreecommitdiff
path: root/attr.c
diff options
context:
space:
mode:
Diffstat (limited to 'attr.c')
-rw-r--r--attr.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/attr.c b/attr.c
index 8ba606c933..6aff6951d3 100644
--- a/attr.c
+++ b/attr.c
@@ -1,5 +1,6 @@
#define NO_THE_INDEX_COMPATIBILITY_MACROS
#include "cache.h"
+#include "exec_cmd.h"
#include "attr.h"
const char git_attr__true[] = "(builtin)true";
@@ -10,6 +11,8 @@ static const char git_attr__unknown[] = "(builtin)unknown";
#define ATTR__UNSET NULL
#define ATTR__UNKNOWN git_attr__unknown
+static const char *attributes_file;
+
/*
* The basic design decision here is that we are not going to have
* insanely large number of attributes.
@@ -462,6 +465,32 @@ static void drop_attr_stack(void)
}
}
+const char *git_etc_gitattributes(void)
+{
+ static const char *system_wide;
+ if (!system_wide)
+ system_wide = system_path(ETC_GITATTRIBUTES);
+ return system_wide;
+}
+
+int git_attr_system(void)
+{
+ return !git_env_bool("GIT_ATTR_NOSYSTEM", 0);
+}
+
+int git_attr_global(void)
+{
+ return !git_env_bool("GIT_ATTR_NOGLOBAL", 0);
+}
+
+static int git_attr_config(const char *var, const char *value, void *dummy)
+{
+ if (!strcmp(var, "core.attributesfile"))
+ return git_config_pathname(&attributes_file, var, value);
+
+ return 0;
+}
+
static void bootstrap_attr_stack(void)
{
if (!attr_stack) {
@@ -472,6 +501,25 @@ static void bootstrap_attr_stack(void)
elem->prev = attr_stack;
attr_stack = elem;
+ if (git_attr_system()) {
+ elem = read_attr_from_file(git_etc_gitattributes(), 1);
+ if (elem) {
+ elem->origin = NULL;
+ elem->prev = attr_stack;
+ attr_stack = elem;
+ }
+ }
+
+ git_config(git_attr_config, NULL);
+ if (git_attr_global() && attributes_file) {
+ elem = read_attr_from_file(attributes_file, 1);
+ if (elem) {
+ elem->origin = NULL;
+ elem->prev = attr_stack;
+ attr_stack = elem;
+ }
+ }
+
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
elem = read_attr(GITATTRIBUTES_FILE, 1);
elem->origin = strdup("");
@@ -499,7 +547,9 @@ static void prepare_attr_stack(const char *path, int dirlen)
/*
* At the bottom of the attribute stack is the built-in
- * set of attribute definitions. Then, contents from
+ * set of attribute definitions, followed by the contents
+ * of $(prefix)/etc/gitattributes and a file specified by
+ * core.attributesfile. Then, contents from
* .gitattribute files from directories closer to the
* root to the ones in deeper directories are pushed
* to the stack. Finally, at the very top of the stack