git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/2] Add support for a shared config file

From
Nathan W. Panike <nathan.panike@gmail.com>
Date
Nov 25, 2010, 17:21 UTC
Message-ID
<f687e6c4830e21db606db99b584864a61e5cf8c3.1290870042.git.nathan.panike@gmail.com>
In-Reply-To
<cover.1290870041.git.nathan.panike@gmail.com>

The idea is that a project develops indigenous aliases that should be shared project-wide. The only way to communicate this now is by channels outside of git--email or IRC or such. We add support for the case where a project configuration can be in .gitconfig in the top level of the repository.

Signed-off-by: Nathan W. Panike <nathan.panike@gmail.com>
---
 builtin/config.c |    9 ++++++++-
 config.c         |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)
diff --git a/builtin/config.c b/builtin/config.c
index ca4a0db..26c679d 100644
--- a/builtin/config.c
+++ b/builtin/config.c
@@ -154,7 +154,7 @@ static int get_value(const char *key_, const char *regex_)
 {
 	int ret = -1;
 	char *tl;
-	char *global = NULL, *repo_config = NULL;
+	char *global = NULL, *repo_config = NULL, *shared = NULL;
 	const char *system_wide = NULL, *local;
 
 	local = config_exclusive_filename;
@@ -165,6 +165,8 @@ static int get_value(const char *key_, const char *regex_)
 			global = xstrdup(mkpath("%s/.gitconfig", home));
 		if (git_config_system())
 			system_wide = git_etc_gitconfig();
+		if(git_config_shared())
+			shared=xstrdup(".gitconfig");
 	}
 
 	key = xstrdup(key_);
@@ -198,11 +200,15 @@ static int get_value(const char *key_, const char *regex_)
 		git_config_from_file(show_config, system_wide, NULL);
 	if (do_all && global)
 		git_config_from_file(show_config, global, NULL);
+	if (do_all && shared) 
+		git_config_from_shared_file(show_config, shared, NULL);	
 	if (do_all)
 		git_config_from_file(show_config, local, NULL);
 	git_config_from_parameters(show_config, NULL);
 	if (!do_all && !seen)
 		git_config_from_file(show_config, local, NULL);
+	if (!do_all && !seen && shared) 
+		git_config_from_shared_file(show_config, shared, NULL);	
 	if (!do_all && !seen && global)
 		git_config_from_file(show_config, global, NULL);
 	if (!do_all && !seen && system_wide)
@@ -222,6 +228,7 @@ static int get_value(const char *key_, const char *regex_)
 free_strings:
 	free(repo_config);
 	free(global);
+	free(shared);
 	return ret;
 }
 
diff --git a/config.c b/config.c
index c63d683..a9e6bec 100644
--- a/config.c
+++ b/config.c
@@ -795,6 +795,38 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 	return ret;
 }
 
+struct config_interceptor {
+	config_fn_t fn;
+	void* data;
+};
+
+/*
+ * The purpose of this function is to keep a malicious contributor from
+ * poisoning our configuration.  The idea of a shared configuration it to
+ * pass around helpful stuff like aliases, but we do not want to allow someone
+ * to say, change our email address or the url of the remote.
+ */
+
+static int config_interceptor_fn(const char*name, const char* value, void* data)
+{
+	int ret=0;
+	struct config_interceptor *ci = (struct config_interceptor*)data;
+	if( !ci ) {
+		return -1;
+	}
+	if(!prefixcmp(name,"alias."))
+		ret = (*ci->fn)(name,value,ci->data);
+	return ret;
+}
+
+int git_config_from_shared_file(config_fn_t fn,const char* filename, void* data)
+{
+	struct config_interceptor ci;
+	ci.fn=fn;
+	ci.data=data;	
+	return git_config_from_file(config_interceptor_fn,filename,&ci);
+}
+
 const char *git_etc_gitconfig(void)
 {
 	static const char *system_wide;
@@ -819,6 +851,11 @@ int git_config_global(void)
 	return !git_env_bool("GIT_CONFIG_NOGLOBAL", 0);
 }
 
+int git_config_shared(void)
+{
+	return !git_env_bool("GIT_CONFIG_NOSHARED", 0);
+}
+
 int git_config_from_parameters(config_fn_t fn, void *data)
 {
 	static int loaded_environment;
@@ -840,7 +877,8 @@ int git_config(config_fn_t fn, void *data)
 	int ret = 0, found = 0;
 	char *repo_config = NULL;
 	const char *home = NULL;
-
+	const char * shared = NULL;
+	
 	/* Setting $GIT_CONFIG makes git read _only_ the given config file. */
 	if (config_exclusive_filename)
 		return git_config_from_file(fn, config_exclusive_filename, data);
@@ -860,6 +898,15 @@ int git_config(config_fn_t fn, void *data)
 		free(user_config);
 	}
 
+	if (git_config_shared()) {
+		char *shared_config=xstrdup(".gitconfig");
+		if (!access(shared_config, R_OK)) {
+			ret += git_config_from_shared_file(fn, shared_config, data);
+			found += 1;
+		}
+		free(shared_config);
+	}
+	
 	repo_config = git_pathdup("config");
 	if (!access(repo_config, R_OK)) {
 		ret += git_config_from_file(fn, repo_config, data);
-- 
1.7.3.2.347.gd33a62
Previous: Nathan W. PanikeNext: Thiago Farina
Message 2 of 6 in “Create a shared config file”
  1. 0/2 Create a shared config fileNathan W. Panike, Nov 27, 2010
  2. 1/2 Add support for a shared config fileNathan W. Panike, Nov 25, 2010
  3. Thiago FarinaNov 27, 2010
  4. 2/2 Document toplevel gitconfig fileNathan W. Panike, Nov 25, 2010
  5. Jonathan NiederNov 27, 2010
  6. Nguyen Thai Ngoc DuyNov 27, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.