Merge branch 'jk/maint-pass-c-config-in-env'
authorJunio C Hamano <gitster@pobox.com>
Wed, 8 Sep 2010 16:17:00 +0000 (09:17 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 8 Sep 2010 16:17:00 +0000 (09:17 -0700)
* jk/maint-pass-c-config-in-env:
  do not pass "git -c foo=bar" params to transport helpers
  pass "git -c foo=bar" params through environment

cache.h
config.c
environment.c
git.c
t/t5400-send-pack.sh

diff --git a/cache.h b/cache.h
index be02a42..abbe083 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -378,6 +378,7 @@ static inline enum object_type object_type(unsigned int mode)
 #define GRAFT_ENVIRONMENT "GIT_GRAFT_FILE"
 #define TEMPLATE_DIR_ENVIRONMENT "GIT_TEMPLATE_DIR"
 #define CONFIG_ENVIRONMENT "GIT_CONFIG"
+#define CONFIG_DATA_ENVIRONMENT "GIT_CONFIG_PARAMETERS"
 #define EXEC_PATH_ENVIRONMENT "GIT_EXEC_PATH"
 #define CEILING_DIRECTORIES_ENVIRONMENT "GIT_CEILING_DIRECTORIES"
 #define NO_REPLACE_OBJECTS_ENVIRONMENT "GIT_NO_REPLACE_OBJECTS"
@@ -396,7 +397,7 @@ static inline enum object_type object_type(unsigned int mode)
  * environment creation or simple walk of the list.
  * The number of non-NULL entries is available as a macro.
  */
-#define LOCAL_REPO_ENV_SIZE 8
+#define LOCAL_REPO_ENV_SIZE 9
 extern const char *const local_repo_env[LOCAL_REPO_ENV_SIZE + 1];
 
 extern int is_bare_repository_cfg;
@@ -973,7 +974,9 @@ extern int update_server_info(int);
 typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int git_default_config(const char *, const char *, void *);
 extern int git_config_from_file(config_fn_t fn, const char *, void *);
+extern void git_config_push_parameter(const char *text);
 extern int git_config_parse_parameter(const char *text);
+extern int git_config_parse_environment(void);
 extern int git_config_from_parameters(config_fn_t fn, void *data);
 extern int git_config(config_fn_t fn, void *);
 extern int git_parse_ulong(const char *, unsigned long *);
index cdcf583..c2c995f 100644 (file)
--- a/config.c
+++ b/config.c
@@ -8,6 +8,7 @@
 #include "cache.h"
 #include "exec_cmd.h"
 #include "strbuf.h"
+#include "quote.h"
 
 #define MAXNAME (256)
 
@@ -34,6 +35,19 @@ static void lowercase(char *p)
                *p = tolower(*p);
 }
 
+void git_config_push_parameter(const char *text)
+{
+       struct strbuf env = STRBUF_INIT;
+       const char *old = getenv(CONFIG_DATA_ENVIRONMENT);
+       if (old) {
+               strbuf_addstr(&env, old);
+               strbuf_addch(&env, ' ');
+       }
+       sq_quote_buf(&env, text);
+       setenv(CONFIG_DATA_ENVIRONMENT, env.buf, 1);
+       strbuf_release(&env);
+}
+
 int git_config_parse_parameter(const char *text)
 {
        struct config_item *ct;
@@ -61,6 +75,37 @@ int git_config_parse_parameter(const char *text)
        return 0;
 }
 
+int git_config_parse_environment(void) {
+       const char *env = getenv(CONFIG_DATA_ENVIRONMENT);
+       char *envw;
+       const char **argv = NULL;
+       int nr = 0, alloc = 0;
+       int i;
+
+       if (!env)
+               return 0;
+       /* sq_dequote will write over it */
+       envw = xstrdup(env);
+
+       if (sq_dequote_to_argv(envw, &argv, &nr, &alloc) < 0) {
+               free(envw);
+               return error("bogus format in " CONFIG_DATA_ENVIRONMENT);
+       }
+
+       for (i = 0; i < nr; i++) {
+               if (git_config_parse_parameter(argv[i]) < 0) {
+                       error("bogus config parameter: %s", argv[i]);
+                       free(argv);
+                       free(envw);
+                       return -1;
+               }
+       }
+
+       free(argv);
+       free(envw);
+       return 0;
+}
+
 static int get_next_char(void)
 {
        int c;
@@ -773,7 +818,14 @@ int git_config_global(void)
 
 int git_config_from_parameters(config_fn_t fn, void *data)
 {
+       static int loaded_environment;
        const struct config_item *ct;
+
+       if (!loaded_environment) {
+               if (git_config_parse_environment() < 0)
+                       return -1;
+               loaded_environment = 1;
+       }
        for (ct = config_parameters; ct; ct = ct->next)
                if (fn(ct->name, ct->value, data) < 0)
                        return -1;
@@ -812,10 +864,9 @@ int git_config(config_fn_t fn, void *data)
        }
        free(repo_config);
 
-       if (config_parameters) {
-               ret += git_config_from_parameters(fn, data);
+       ret += git_config_from_parameters(fn, data);
+       if (config_parameters)
                found += 1;
-       }
 
        if (found == 0)
                return -1;
index eeb2687..9425606 100644 (file)
@@ -73,6 +73,7 @@ static char *git_object_dir, *git_index_file, *git_refs_dir, *git_graft_file;
 const char * const local_repo_env[LOCAL_REPO_ENV_SIZE + 1] = {
        ALTERNATE_DB_ENVIRONMENT,
        CONFIG_ENVIRONMENT,
+       CONFIG_DATA_ENVIRONMENT,
        DB_ENVIRONMENT,
        GIT_DIR_ENVIRONMENT,
        GIT_WORK_TREE_ENVIRONMENT,
diff --git a/git.c b/git.c
index 8de4810..d64ab1a 100644 (file)
--- a/git.c
+++ b/git.c
@@ -137,7 +137,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                                fprintf(stderr, "-c expects a configuration string\n" );
                                usage(git_usage_string);
                        }
-                       git_config_parse_parameter((*argv)[1]);
+                       git_config_push_parameter((*argv)[1]);
                        (*argv)++;
                        (*argc)--;
                } else {
index c718253..5bcf0b8 100755 (executable)
@@ -94,6 +94,29 @@ test_expect_success 'refuse deleting push with denyDeletes' '
        test_must_fail git send-pack ./victim :extra master
 '
 
+test_expect_success 'cannot override denyDeletes with git -c send-pack' '
+       (
+               cd victim &&
+               test_might_fail git branch -D extra &&
+               git config receive.denyDeletes true &&
+               git branch extra master
+       ) &&
+       test_must_fail git -c receive.denyDeletes=false \
+                                       send-pack ./victim :extra master
+'
+
+test_expect_success 'override denyDeletes with git -c receive-pack' '
+       (
+               cd victim &&
+               test_might_fail git branch -D extra &&
+               git config receive.denyDeletes true &&
+               git branch extra master
+       ) &&
+       git send-pack \
+               --receive-pack="git -c receive.denyDeletes=false receive-pack" \
+               ./victim :extra master
+'
+
 test_expect_success 'denyNonFastforwards trumps --force' '
        (
            cd victim &&