Merge branch 'es/format-patch-interdiff' into es/format-patch-rangediff
[gitweb.git] / builtin / config.c
index 2f78a02ca1d893c7c0a57b56dfba65d291acf49e..2c93a289a7255c69260a806cc064f00170453531 100644 (file)
@@ -61,12 +61,13 @@ static int show_origin;
 #define TYPE_BOOL_OR_INT       3
 #define TYPE_PATH              4
 #define TYPE_EXPIRY_DATE       5
+#define TYPE_COLOR             6
 
 #define OPT_CALLBACK_VALUE(s, l, v, h, i) \
        { OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
        PARSE_OPT_NONEG, option_parse_type, (i) }
 
-static struct option builtin_config_options[];
+static NORETURN void usage_builtin_config(void);
 
 static int option_parse_type(const struct option *opt, const char *arg,
                             int unset)
@@ -94,6 +95,8 @@ static int option_parse_type(const struct option *opt, const char *arg,
                        new_type = TYPE_PATH;
                else if (!strcmp(arg, "expiry-date"))
                        new_type = TYPE_EXPIRY_DATE;
+               else if (!strcmp(arg, "color"))
+                       new_type = TYPE_COLOR;
                else
                        die(_("unrecognized --type argument, %s"), arg);
        }
@@ -108,8 +111,7 @@ static int option_parse_type(const struct option *opt, const char *arg,
                 * --type=int'.
                 */
                error("only one type at a time.");
-               usage_with_options(builtin_config_usage,
-                       builtin_config_options);
+               usage_builtin_config();
        }
        *to_type = new_type;
 
@@ -154,11 +156,16 @@ static struct option builtin_config_options[] = {
        OPT_END(),
 };
 
+static NORETURN void usage_builtin_config(void)
+{
+       usage_with_options(builtin_config_usage, builtin_config_options);
+}
+
 static void check_argc(int argc, int min, int max) {
        if (argc >= min && argc <= max)
                return;
        error("wrong number of arguments");
-       usage_with_options(builtin_config_usage, builtin_config_options);
+       usage_builtin_config();
 }
 
 static void show_config_origin(struct strbuf *buf)
@@ -230,6 +237,11 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
                        if (git_config_expiry_date(&t, key_, value_) < 0)
                                return -1;
                        strbuf_addf(buf, "%"PRItime, t);
+               } else if (type == TYPE_COLOR) {
+                       char v[COLOR_MAXLEN];
+                       if (git_config_color(v, key_, value_) < 0)
+                               return -1;
+                       strbuf_addstr(buf, v);
                } else if (value_) {
                        strbuf_addstr(buf, value_);
                } else {
@@ -375,8 +387,22 @@ static char *normalize_value(const char *key, const char *value)
                else
                        return xstrdup(v ? "true" : "false");
        }
+       if (type == TYPE_COLOR) {
+               char v[COLOR_MAXLEN];
+               if (git_config_color(v, key, value))
+                       die("cannot parse color '%s'", value);
 
-       die("BUG: cannot normalize type %d", type);
+               /*
+                * The contents of `v` now contain an ANSI escape
+                * sequence, not suitable for including within a
+                * configuration file. Treat the above as a
+                * "sanity-check", and return the given value, which we
+                * know is representable as valid color code.
+                */
+               return xstrdup(value);
+       }
+
+       BUG("cannot normalize type %d", type);
 }
 
 static int get_color_found;
@@ -574,12 +600,15 @@ int cmd_config(int argc, const char **argv, const char *prefix)
        if (use_global_config + use_system_config + use_local_config +
            !!given_config_source.file + !!given_config_source.blob > 1) {
                error("only one config file at a time.");
-               usage_with_options(builtin_config_usage, builtin_config_options);
+               usage_builtin_config();
        }
 
        if (use_local_config && nongit)
                die(_("--local can only be used inside a git repository"));
 
+       if (given_config_source.blob && nongit)
+               die(_("--blob can only be used inside a git repository"));
+
        if (given_config_source.file &&
                        !strcmp(given_config_source.file, "-")) {
                given_config_source.file = NULL;
@@ -635,12 +664,12 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 
        if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && type) {
                error("--get-color and variable type are incoherent");
-               usage_with_options(builtin_config_usage, builtin_config_options);
+               usage_builtin_config();
        }
 
        if (HAS_MULTI_BITS(actions)) {
                error("only one action at a time.");
-               usage_with_options(builtin_config_usage, builtin_config_options);
+               usage_builtin_config();
        }
        if (actions == 0)
                switch (argc) {
@@ -648,25 +677,24 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                case 2: actions = ACTION_SET; break;
                case 3: actions = ACTION_SET_ALL; break;
                default:
-                       usage_with_options(builtin_config_usage, builtin_config_options);
+                       usage_builtin_config();
                }
        if (omit_values &&
            !(actions == ACTION_LIST || actions == ACTION_GET_REGEXP)) {
                error("--name-only is only applicable to --list or --get-regexp");
-               usage_with_options(builtin_config_usage, builtin_config_options);
+               usage_builtin_config();
        }
 
        if (show_origin && !(actions &
                (ACTION_GET|ACTION_GET_ALL|ACTION_GET_REGEXP|ACTION_LIST))) {
                error("--show-origin is only applicable to --get, --get-all, "
                          "--get-regexp, and --list.");
-               usage_with_options(builtin_config_usage, builtin_config_options);
+               usage_builtin_config();
        }
 
        if (default_value && !(actions & ACTION_GET)) {
                error("--default is only applicable to --get");
-               usage_with_options(builtin_config_usage,
-                       builtin_config_options);
+               usage_builtin_config();
        }
 
        if (actions & PAGING_ACTIONS)