builtin-repo-config.con commit gitweb: Support for snapshot (cb9c6e5)
   1#include "builtin.h"
   2#include "cache.h"
   3#include <regex.h>
   4
   5static const char git_config_set_usage[] =
   6"git-repo-config [ --bool | --int ] [--get | --get-all | --get-regexp | --replace-all | --unset | --unset-all] name [value [value_regex]] | --list";
   7
   8static char *key;
   9static regex_t *key_regexp;
  10static regex_t *regexp;
  11static int show_keys;
  12static int use_key_regexp;
  13static int do_all;
  14static int do_not_match;
  15static int seen;
  16static enum { T_RAW, T_INT, T_BOOL } type = T_RAW;
  17
  18static int show_all_config(const char *key_, const char *value_)
  19{
  20        if (value_)
  21                printf("%s=%s\n", key_, value_);
  22        else
  23                printf("%s\n", key_);
  24        return 0;
  25}
  26
  27static int show_config(const char* key_, const char* value_)
  28{
  29        char value[256];
  30        const char *vptr = value;
  31        int dup_error = 0;
  32
  33        if (!use_key_regexp && strcmp(key_, key))
  34                return 0;
  35        if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0))
  36                return 0;
  37        if (regexp != NULL &&
  38                         (do_not_match ^
  39                          regexec(regexp, (value_?value_:""), 0, NULL, 0)))
  40                return 0;
  41
  42        if (show_keys)
  43                printf("%s ", key_);
  44        if (seen && !do_all)
  45                dup_error = 1;
  46        if (type == T_INT)
  47                sprintf(value, "%d", git_config_int(key_, value_?value_:""));
  48        else if (type == T_BOOL)
  49                vptr = git_config_bool(key_, value_) ? "true" : "false";
  50        else
  51                vptr = value_?value_:"";
  52        seen++;
  53        if (dup_error) {
  54                error("More than one value for the key %s: %s",
  55                                key_, vptr);
  56        }
  57        else
  58                printf("%s\n", vptr);
  59
  60        return 0;
  61}
  62
  63static int get_value(const char* key_, const char* regex_)
  64{
  65        int ret = -1;
  66        char *tl;
  67        char *global = NULL, *repo_config = NULL;
  68        const char *local;
  69
  70        local = getenv("GIT_CONFIG");
  71        if (!local) {
  72                const char *home = getenv("HOME");
  73                local = getenv("GIT_CONFIG_LOCAL");
  74                if (!local)
  75                        local = repo_config = strdup(git_path("config"));
  76                if (home)
  77                        global = strdup(mkpath("%s/.gitconfig", home));
  78        }
  79
  80        key = strdup(key_);
  81        for (tl=key+strlen(key)-1; tl >= key && *tl != '.'; --tl)
  82                *tl = tolower(*tl);
  83        for (tl=key; *tl && *tl != '.'; ++tl)
  84                *tl = tolower(*tl);
  85
  86        if (use_key_regexp) {
  87                key_regexp = (regex_t*)malloc(sizeof(regex_t));
  88                if (regcomp(key_regexp, key, REG_EXTENDED)) {
  89                        fprintf(stderr, "Invalid key pattern: %s\n", key_);
  90                        goto free_strings;
  91                }
  92        }
  93
  94        if (regex_) {
  95                if (regex_[0] == '!') {
  96                        do_not_match = 1;
  97                        regex_++;
  98                }
  99
 100                regexp = (regex_t*)malloc(sizeof(regex_t));
 101                if (regcomp(regexp, regex_, REG_EXTENDED)) {
 102                        fprintf(stderr, "Invalid pattern: %s\n", regex_);
 103                        goto free_strings;
 104                }
 105        }
 106
 107        if (do_all && global)
 108                git_config_from_file(show_config, global);
 109        git_config_from_file(show_config, local);
 110        if (!do_all && !seen && global)
 111                git_config_from_file(show_config, global);
 112
 113        free(key);
 114        if (regexp) {
 115                regfree(regexp);
 116                free(regexp);
 117        }
 118
 119        if (do_all)
 120                ret = !seen;
 121        else
 122                ret =  (seen == 1) ? 0 : 1;
 123
 124free_strings:
 125        if (repo_config)
 126                free(repo_config);
 127        if (global)
 128                free(global);
 129        return ret;
 130}
 131
 132int cmd_repo_config(int argc, const char **argv, const char *prefix)
 133{
 134        int nongit = 0;
 135        setup_git_directory_gently(&nongit);
 136
 137        while (1 < argc) {
 138                if (!strcmp(argv[1], "--int"))
 139                        type = T_INT;
 140                else if (!strcmp(argv[1], "--bool"))
 141                        type = T_BOOL;
 142                else if (!strcmp(argv[1], "--list") || !strcmp(argv[1], "-l"))
 143                        return git_config(show_all_config);
 144                else
 145                        break;
 146                argc--;
 147                argv++;
 148        }
 149
 150        switch (argc) {
 151        case 2:
 152                return get_value(argv[1], NULL);
 153        case 3:
 154                if (!strcmp(argv[1], "--unset"))
 155                        return git_config_set(argv[2], NULL);
 156                else if (!strcmp(argv[1], "--unset-all"))
 157                        return git_config_set_multivar(argv[2], NULL, NULL, 1);
 158                else if (!strcmp(argv[1], "--get"))
 159                        return get_value(argv[2], NULL);
 160                else if (!strcmp(argv[1], "--get-all")) {
 161                        do_all = 1;
 162                        return get_value(argv[2], NULL);
 163                } else if (!strcmp(argv[1], "--get-regexp")) {
 164                        show_keys = 1;
 165                        use_key_regexp = 1;
 166                        do_all = 1;
 167                        return get_value(argv[2], NULL);
 168                } else
 169
 170                        return git_config_set(argv[1], argv[2]);
 171        case 4:
 172                if (!strcmp(argv[1], "--unset"))
 173                        return git_config_set_multivar(argv[2], NULL, argv[3], 0);
 174                else if (!strcmp(argv[1], "--unset-all"))
 175                        return git_config_set_multivar(argv[2], NULL, argv[3], 1);
 176                else if (!strcmp(argv[1], "--get"))
 177                        return get_value(argv[2], argv[3]);
 178                else if (!strcmp(argv[1], "--get-all")) {
 179                        do_all = 1;
 180                        return get_value(argv[2], argv[3]);
 181                } else if (!strcmp(argv[1], "--get-regexp")) {
 182                        show_keys = 1;
 183                        use_key_regexp = 1;
 184                        do_all = 1;
 185                        return get_value(argv[2], argv[3]);
 186                } else if (!strcmp(argv[1], "--replace-all"))
 187
 188                        return git_config_set_multivar(argv[2], argv[3], NULL, 1);
 189                else
 190
 191                        return git_config_set_multivar(argv[1], argv[2], argv[3], 0);
 192        case 5:
 193                if (!strcmp(argv[1], "--replace-all"))
 194                        return git_config_set_multivar(argv[2], argv[3], argv[4], 1);
 195        case 1:
 196        default:
 197                usage(git_config_set_usage);
 198        }
 199        return 0;
 200}