All of lore.kernel.org
 help / color / mirror / Atom feed
From: Petr Onderka <gsvick@gmail.com>
To: git@vger.kernel.org
Cc: Henrik Grubbstrm <grubba@grubba.org>
Subject: [PATCH/RFC] Add global and system-wide gitattributes
Date: Wed, 11 Aug 2010 01:04:06 +0000	[thread overview]
Message-ID: <1281488646-7108-1-git-send-email-gsvick@gmail.com> (raw)

Allow gitattributes to be set globally and system wide in ~/.giattributes
and $(prefix)/etc/gitattributes files, respectively. This way, settings
for particular file types can be set in one place and apply for all user's
repositories.

Contents of those two files are added to the attr_stack struct that
contains content of info/attributes, so that prepare_attr_stack()
keeps working as is and doesn't have to pop and then put back two more
structs (in addition to the "info" one).

Some parts of the code were copied from the implementation of the same
functionality in config.c.

Signed-off-by: Petr Onderka <gsvick@gmail.com>
---
Hi,

I thought this feature would be useful for me, so I coded it up.
What do you think? Is it ready to be included to the official repository as is?

 Documentation/gitattributes.txt |    5 ++-
 Makefile                        |    6 +++++
 attr.c                          |   43 ++++++++++++++++++++++++++++++++------
 configure.ac                    |    7 ++++++
 4 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 564586b..351b014 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -7,7 +7,7 @@ gitattributes - defining attributes per path
 
 SYNOPSIS
 --------
-$GIT_DIR/info/attributes, .gitattributes
+$GIT_DIR/info/attributes, /etc/gitattributes, ~/.gitattributes, .gitattributes
 
 
 DESCRIPTION
@@ -58,7 +58,8 @@ attribute.  The rules how the pattern matches paths are the
 same as in `.gitignore` files; see linkgit:gitignore[5].
 
 When deciding what attributes are assigned to a path, git
-consults `$GIT_DIR/info/attributes` file (which has the highest
+consults `$GIT_DIR/info/attributes`, `~/.gitattributes`
+and `$(prefix)/etc/gitconfig` files (in order of decreasing
 precedence), `.gitattributes` file in the same directory as the
 path in question, and its parent directories up to the toplevel of the
 work tree (the further the directory that contains `.gitattributes`
diff --git a/Makefile b/Makefile
index bc3c570..eadd2d7 100644
--- a/Makefile
+++ b/Makefile
@@ -268,6 +268,7 @@ STRIP ?= strip
 #   infodir
 #   htmldir
 #   ETC_GITCONFIG (but not sysconfdir)
+#   ETC_GITATTRIBUTES
 # can be specified as a relative path some/where/else;
 # this is interpreted as relative to $(prefix) and "git" at
 # runtime figures out where they are based on the path to the executable.
@@ -286,9 +287,11 @@ htmldir = share/doc/git-doc
 ifeq ($(prefix),/usr)
 sysconfdir = /etc
 ETC_GITCONFIG = $(sysconfdir)/gitconfig
+ETC_GITATTRIBUTES = $(sysconfdir)/gitattributes
 else
 sysconfdir = $(prefix)/etc
 ETC_GITCONFIG = etc/gitconfig
+ETC_GITATTRIBUTES = etc/gitattributes
 endif
 lib = lib
 # DESTDIR=
@@ -1502,6 +1505,7 @@ endif
 
 SHA1_HEADER_SQ = $(subst ','\'',$(SHA1_HEADER))
 ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG))
+ETC_GITATTRIBUTES_SQ = $(subst ','\'',$(ETC_GITATTRIBUTES))
 
 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
 bindir_SQ = $(subst ','\'',$(bindir))
@@ -1872,6 +1876,8 @@ builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \
 
 config.s config.o: EXTRA_CPPFLAGS = -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"'
 
+attr.s attr.o: EXTRA_CPPFLAGS = -DETC_GITATTRIBUTES='"$(ETC_GITATTRIBUTES_SQ)"'
+
 http.s http.o: EXTRA_CPPFLAGS = -DGIT_USER_AGENT='"git/$(GIT_VERSION)"'
 
 ifdef NO_EXPAT
diff --git a/attr.c b/attr.c
index 8ba606c..b1c3a30 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";
@@ -326,16 +327,16 @@ static struct attr_stack *read_attr_from_array(const char **list)
 static enum git_attr_direction direction;
 static struct index_state *use_index;
 
-static struct attr_stack *read_attr_from_file(const char *path, int macro_ok)
+static struct attr_stack *read_attr_from_file(const char *path, int macro_ok, struct attr_stack *res)
 {
 	FILE *fp = fopen(path, "r");
-	struct attr_stack *res;
 	char buf[2048];
 	int lineno = 0;
 
 	if (!fp)
-		return NULL;
-	res = xcalloc(1, sizeof(*res));
+		return res;
+	if (!res)
+		res = xcalloc(1, sizeof(*res));
 	while (fgets(buf, sizeof(buf), fp))
 		handle_attr_line(res, buf, path, ++lineno, macro_ok);
 	fclose(fp);
@@ -407,10 +408,10 @@ static struct attr_stack *read_attr(const char *path, int macro_ok)
 	if (direction == GIT_ATTR_CHECKOUT) {
 		res = read_attr_from_index(path, macro_ok);
 		if (!res)
-			res = read_attr_from_file(path, macro_ok);
+			res = read_attr_from_file(path, macro_ok, NULL);
 	}
 	else if (direction == GIT_ATTR_CHECKIN) {
-		res = read_attr_from_file(path, macro_ok);
+		res = read_attr_from_file(path, macro_ok, NULL);
 		if (!res)
 			/*
 			 * There is no checked out .gitattributes file there, but
@@ -462,8 +463,28 @@ 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 void bootstrap_attr_stack(void)
 {
+	const char *home;
+
 	if (!attr_stack) {
 		struct attr_stack *elem;
 
@@ -480,7 +501,15 @@ static void bootstrap_attr_stack(void)
 			debug_push(elem);
 		}
 
-		elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
+		elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1, NULL);
+		home = get_home_directory();
+		if (git_attr_global() && home) {
+			char *user_attr = xstrdup(mkpath("%s/%s", home, GITATTRIBUTES_FILE));
+			elem = read_attr_from_file(user_attr, 1, elem);
+			free(user_attr);
+		}
+		if (git_attr_system())
+			elem = read_attr_from_file(git_etc_gitattributes(), 1, elem);
 		if (!elem)
 			elem = xcalloc(1, sizeof(*elem));
 		elem->origin = NULL;
diff --git a/configure.ac b/configure.ac
index 5601e8b..773b835 100644
--- a/configure.ac
+++ b/configure.ac
@@ -285,6 +285,13 @@ GIT_PARSE_WITH_SET_MAKE_VAR(gitconfig, ETC_GITCONFIG,
 			If VALUE is not fully qualified it will be interpretted
 			as a path relative to the computed prefix at runtime.)
 
+# Allow user to set ETC_GITATTRIBUTS variable
+GIT_PARSE_WITH_SET_MAKE_VAR(gitattributes, ETC_GITATTRIBUTES,
+			Use VALUE instead of /etc/gitattributes as the
+			global git attributes file.
+			If VALUE is not fully qualified it will be interpretted
+			as a path relative to the computed prefix at runtime.)
+
 #
 # Allow user to set the default pager
 GIT_PARSE_WITH_SET_MAKE_VAR(pager, DEFAULT_PAGER,
-- 
1.7.1.msysgit.0.10.g9ffa0

             reply	other threads:[~2010-08-11  1:04 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-08-11  1:04 Petr Onderka [this message]
2010-08-11  9:20 ` [PATCH/RFC] Add global and system-wide gitattributes Henrik Grubbström
2010-08-11 10:50   ` Petr Onderka
2010-08-11 12:31 ` Matthieu Moy
2010-08-11 22:19 ` Junio C Hamano
2010-08-16 16:51   ` Petr Onderka
2010-08-16 16:56     ` [PATCH v2] " Petr Onderka
2010-08-25  9:55       ` Štěpán Němec
2010-08-28 17:33         ` Matthieu Moy
2010-08-30  5:34           ` Junio C Hamano
2010-08-30  9:09             ` Štěpán Němec
2010-08-28 18:35       ` Matthieu Moy
2010-08-28 18:41         ` [PATCH] core.attributesfile: a fix, a simplification, and a test Matthieu Moy
2010-08-29 10:32           ` [PATCH v3?] Add global and system-wide gitattributes Štěpán Němec
2010-08-30  8:04             ` Junio C Hamano
2010-08-30  8:26               ` Matthieu Moy
2010-08-30 20:47                 ` Junio C Hamano
2010-08-30 21:11                   ` Junio C Hamano
2010-08-30 22:55                     ` Matthieu Moy
2010-08-30 23:15                       ` [PATCH 1/3 v2] tests: factor HOME=$(pwd) in test-lib.sh Matthieu Moy
2010-08-31  7:42                         ` Ævar Arnfjörð Bjarmason
2010-09-01  7:56                           ` Ævar Arnfjörð Bjarmason
2010-09-01 15:24                             ` Junio C Hamano
2010-09-01 15:40                               ` Ævar Arnfjörð Bjarmason
2010-09-01 16:57                                 ` Matthieu Moy
2010-08-30 23:15                       ` [PATCH 2/3] don't write to git_log_output_encoding outside git_config() Matthieu Moy
2010-09-02  8:56                         ` Matthieu Moy
2010-09-02 15:49                           ` Junio C Hamano
2010-08-30 23:15                       ` [PATCH 3/3 v4] Add global and system-wide gitattributes Matthieu Moy
2010-08-31 22:41                         ` Matthieu Moy
2010-08-31 22:42                           ` [PATCH] " Matthieu Moy
2010-08-31 23:56                           ` [PATCH 3/3 v4] " Junio C Hamano
2010-08-30  9:50               ` [PATCH] tests: factor HOME=$(pwd) in test-lib.sh Matthieu Moy
2010-08-30 10:22                 ` Ævar Arnfjörð Bjarmason
2010-08-30 10:54                   ` Matthieu Moy
2010-08-30 11:08                     ` Ævar Arnfjörð Bjarmason

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1281488646-7108-1-git-send-email-gsvick@gmail.com \
    --to=gsvick@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=grubba@grubba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.