From 57f2b8424ade734550731392e90b8f738d478e02 Mon Sep 17 00:00:00 2001
From: Junio C Hamano <gitster@pobox.com>
Date: Mon, 26 Nov 2007 14:30:28 -0800
Subject: [PATCH 1/2] "color.diff = true" is not "always" anymore.

Too many people got burned by setting color.diff and color.status to
true when they really should have set it to "auto".

This makes only "always" to do the unconditional colorization, and
change the meaning of "true" to the same as "auto": colorize only when
we are talking to a terminal.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 color.c | 32 +++++++++++++++++++-------------
 1 file changed, 19 insertions(+), 13 deletions(-)

diff --git a/color.c b/color.c
index 124ba331c7f..97cfbda31ac 100644
--- a/color.c
+++ b/color.c
@@ -118,21 +118,27 @@ bad:
 
 int git_config_colorbool(const char *var, const char *value)
 {
-	if (!value)
-		return 1;
-	if (!strcasecmp(value, "auto")) {
-		if (isatty(1) || (pager_in_use && pager_use_color)) {
-			char *term = getenv("TERM");
-			if (term && strcmp(term, "dumb"))
-				return 1;
-		}
-		return 0;
+	if (value) {
+		if (!strcasecmp(value, "never"))
+			return 0;
+		if (!strcasecmp(value, "always"))
+			return 1;
+		if (!strcasecmp(value, "auto"))
+			goto auto_color;
 	}
-	if (!strcasecmp(value, "never"))
+
+	/* Missing or explicit false to turn off colorization */
+	if (!git_config_bool(var, value))
 		return 0;
-	if (!strcasecmp(value, "always"))
-		return 1;
-	return git_config_bool(var, value);
+
+	/* any normal truth value defaults to 'auto' */
+ auto_color:
+	if (isatty(1) || (pager_in_use && pager_use_color)) {
+		char *term = getenv("TERM");
+		if (term && strcmp(term, "dumb"))
+			return 1;
+	}
+	return 0;
 }
 
 static int color_vfprintf(FILE *fp, const char *color, const char *fmt,

From 9ce0352258a421b654b5db145a42d07cbaef416c Mon Sep 17 00:00:00 2001
From: Junio C Hamano <gitster@pobox.com>
Date: Tue, 27 Nov 2007 22:41:05 -0800
Subject: [PATCH 2/2] git-config --get-color: get configured color

This new option allows scripts to grab color setting from the user
configuration, translated to ANSI color escape sequence.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-config.txt | 16 +++++++++++
 builtin-config.c             | 55 ++++++++++++++++++++++++++++++++++--
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index a592b61e2fe..76404507870 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -20,6 +20,7 @@ SYNOPSIS
 'git-config' [<file-option>] --rename-section old_name new_name
 'git-config' [<file-option>] --remove-section name
 'git-config' [<file-option>] [-z|--null] -l | --list
+'git-config' [<file-option>] --get-color name [default]
 
 DESCRIPTION
 -----------
@@ -134,6 +135,12 @@ See also <<FILES>>.
 	output without getting confused e.g. by values that
 	contain line breaks.
 
+--get-color name default::
+
+	Find the color configured for `name` (e.g. `color.diff.new`) and
+	output it as the ANSI color escape sequence to the standard
+	output.  The optional `default` parameter is used instead, if
+	there is no color configured for `name`.
 
 [[FILES]]
 FILES
@@ -292,6 +299,15 @@ To add a new proxy, without altering any of the existing ones, use
 % git config core.gitproxy '"proxy-command" for example.com'
 ------------
 
+An example to use customized color from the configuration in your
+script:
+
+------------
+#!/bin/sh
+WS=$(git config --get-color color.diff.whitespace "blue reverse")
+RESET=$(git config --get-color "" "reset")
+echo "${WS}your whitespace color or blue reverse${RESET}"
+------------
 
 include::config.txt[]
 
diff --git a/builtin-config.c b/builtin-config.c
index f672c9cccae..4c9ded3b1a1 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -1,8 +1,9 @@
 #include "builtin.h"
 #include "cache.h"
+#include "color.h"
 
 static const char git_config_set_usage[] =
-"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list";
+"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default]";
 
 static char *key;
 static regex_t *key_regexp;
@@ -161,6 +162,53 @@ char *normalize_value(const char *key, const char *value)
 	return normalized;
 }
 
+static int get_color_found;
+static const char *get_color_slot;
+static char parsed_color[COLOR_MAXLEN];
+
+static int git_get_color_config(const char *var, const char *value)
+{
+	if (!strcmp(var, get_color_slot)) {
+		color_parse(value, var, parsed_color);
+		get_color_found = 1;
+	}
+	return 0;
+}
+
+static int get_color(int argc, const char **argv)
+{
+	/*
+	 * grab the color setting for the given slot from the configuration,
+	 * or parse the default value if missing, and return ANSI color
+	 * escape sequence.
+	 *
+	 * e.g.
+	 * git config --get-color color.diff.whitespace "blue reverse"
+	 */
+	const char *def_color = NULL;
+
+	switch (argc) {
+	default:
+		usage(git_config_set_usage);
+	case 2:
+		def_color = argv[1];
+		/* fallthru */
+	case 1:
+		get_color_slot = argv[0];
+		break;
+	}
+
+	get_color_found = 0;
+	parsed_color[0] = '\0';
+	git_config(git_get_color_config);
+
+	if (!get_color_found && def_color)
+		color_parse(def_color, "command line", parsed_color);
+
+	fputs(parsed_color, stdout);
+	return 0;
+}
+
 int cmd_config(int argc, const char **argv, const char *prefix)
 {
 	int nongit = 0;
@@ -234,8 +282,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 				return 1;
 			}
 			return 0;
-		}
-		else
+		} else if (!strcmp(argv[1], "--get-color")) {
+			return get_color(argc-2, argv+2);
+		} else
 			break;
 		argc--;
 		argv++;