Skip to contentSkip to conversation

Create a shared config file

PATCH In review Nathan W. Panike 4 participants 6 messages Jun 15, 2016 Documentation

lore
Share & tools
lore
#0 lore raw

cover Create a shared config file

Configuration should normally be on a per-repository or per-user basis. There are cases where it would be helpful to have a project share configuration across repositories and between developers. Normally this happens only via e-mail or IRC or by word-of-mouth. The solution implemented by these patches is to have a .gitconfig file in the toplevel of the repository.

This is not a finished implementation, as I have no tests written. Instead, this is ``one way to do it.''

Nathan W. Panike (2):
Add support for a shared config file
Document toplevel .gitconfig file

 Documentation/config.txt |   11 ++++++++++
 builtin/config.c         |    9 +++++++-
 config.c                 |   49 +++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 67 insertions(+), 2 deletions(-)
Signature · 1 line
1.7.3.2.347.gd33a62
#1 lore raw
Quoted 5 lines · Nathan W. Panike

Configuration should normally be on a per-repository or per-user basis.  There are cases where it would be helpful to have a project share configuration across repositories and between developers.  Normally this happens only via e-mail or IRC or by word-of-mouth.  The solution implemented by these patches is to have a .gitconfig file in the toplevel of the repository.

Or save the shared config in the repository and add an instruction in $GIT_DIR/config to include such config blob. We can worry less about malicious config that way. If you are extremely nervous about it, you can always point to a specific blob that you have checked.

Signature · 1 line
Duy
#2 lore raw

PATCH 1/2 Add support for a shared config file

In reply to Nathan W. Panike

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.

---
 builtin/config.c |    9 ++++++++-
 config.c         |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 56 insertions(+), 2 deletions(-)
builtin/config.c +8 -1
index ca4a0db..26c679d 100644
@@ -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;
 }
 
config.c +48 -1

73 lines not on this page · raw message

Signature · 1 line
1.7.3.2.347.gd33a62
#3 lore raw

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

Some minor nits (style) below.

Quoted 26 lines · Nathan W. Panike

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.

---
 builtin/config.c |    9 ++++++++-
 config.c         |   49 ++++++++++++++++++++++++++++++++++++++++++++++++-

 2 files changed, 56 insertions(+), 2 deletions(-)
builtin/config.c +1 -1
index ca4a0db..26c679d 100644
@@ -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;

builtin/config.c static int get_value(const char *key_, const char *regex_) · line 169

Quoted 5 lines
builtin/config.c +2 -0
@@ -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");

nit: add a space before and after the =

Quoted 32 lines
builtin/config.c +4 -0
        }
 
        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;
 }

config.c +0 -0
index c63d683..a9e6bec 100644

config.c int git_config_from_file(config_fn_t fn, const char *filename, void *data) · line 802

Quoted 8 lines
config.c +5 -0
@@ -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;
+};
+

Would be good to add a description about what is this structure and what is for?

config.c int git_config_from_file(config_fn_t fn, const char *filename, void *data) · line 812

Quoted 10 lines
config.c +10 -0
+/*
+ * 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;

nit: add space before and after the =

config.c int git_config_from_file(config_fn_t fn, const char *filename, void *data) · line 814

Quoted 2 lines
config.c +2 -0
+       struct config_interceptor *ci = (struct config_interceptor*)data;
+       if( !ci ) {

wrong, wrong.

I think the style used here is:

if (!ci) {

So, add a space after the if, and no spaces in the () please.

config.c int git_config_from_file(config_fn_t fn, const char *filename, void *data) · line 817

Quoted 3 lines
config.c +3 -0
+               return -1;
+       }
+       if(!prefixcmp(name,"alias."))

same thing here about the space after the if

config.c int git_config_from_file(config_fn_t fn, const char *filename, void *data) · line 825

Quoted 8 lines
config.c +8 -0
+               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;

nit: fix this too and the other occurrences below.

#4 lore raw

PATCH 2/2 Document toplevel gitconfig file

In reply to Nathan W. Panike

Try to explain its security implications and how to turn it off.

---
 Documentation/config.txt |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)
Documentation/config.txt +11 -0
index 6a6c0b5..6ec9a0b 100644
@@ -8,6 +8,17 @@ is used to store the configuration for that repository, and
 fallback values for the `.git/config` file. The file `/etc/gitconfig`
 can be used to store a system-wide default configuration.
 
+One can also create a `.gitconfig` file in the toplevel of the
+repository. This config file will then be propogated to collaborators
+when they pull from your repository.  Only `alias` config variables are
+allowed to be set in this `.gitconfig` file.  One can turn off the
+shared `.gitconfig` by setting the environment variable
+'GIT_CONFIG_NOSHARED' to 1; it will then be propogated but will not be
+used for configuration settings.  Note that this is a security issue
+because you are basically allowing someone else to dictate your
+configuration, but should be fine if you pay attention and do not use
+aliases from someone else blindly.
+
 The configuration variables are used by both the git plumbing
 and the porcelains. The variables are divided into sections, wherein
 the fully qualified variable name of the variable itself is the last
Signature · 1 line
1.7.3.2.347.gd33a62
#5 lore raw

Re: [PATCH 2/2] Document toplevel gitconfig file

Documentation/config.txt is used to store the configuration for that repository, and · line 17

Quoted 13 lines · Nathan W. Panike
Documentation/config.txt +7 -0
@@ -8,6 +8,17 @@ is used to store the configuration for that repository, and
 fallback values for the `.git/config` file. The file `/etc/gitconfig`
 can be used to store a system-wide default configuration.
 
+One can also create a `.gitconfig` file in the toplevel of the
+repository. This config file will then be propogated to collaborators
+when they pull from your repository.  Only `alias` config variables are
+allowed to be set in this `.gitconfig` file.  One can turn off the
+shared `.gitconfig` by setting the environment variable
+'GIT_CONFIG_NOSHARED' to 1; it will then be propogated but will not be
+used for configuration settings.

Please no. Why not set up aliases in a setup-aliases.sh script and mention it in your README?

If I clone a repository to investigate it and then a typo results in

	$ git lgo

emptying my $HOME directory, I would not call that a feature.