threads / patch / 11141

patchColor support for "git-add -i"

Subject: [PATCH] Color support for "git-add -i"

## tl;dr

18 messages between Dec 5, 2007 and Dec 7, 2007. Diffs are folded; open one to read it.

replies: 17people: 5as markdown or json

Junio C Hamano· Dec 5, 2007, 10:59 UTC · lore

This is mostly lifted from earlier series by Dan Zwell, but updated to use "git config --get-color" to make it simpler and more consistent with commands written in C.

A new configuration color.interactive variable is like color.diff and color.status, and controls if "git-add -i" uses color.

A set of configuration variables, color.interactive.<slot>, are used to define what color is used for the prompt, header, and help text.

For perl scripts, Git.pm provides $repo->get_color() method, which takes the slot name and the default color, and returns the terminal escape sequence to color the output text.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 * I'd like to have the colored "add -i" by 1.5.4-rc0 so I updated the
   series myself.  Ack, improvements, fixes?
 Documentation/config.txt  |   13 +++++
 git-add--interactive.perl |  121 +++++++++++++++++++++++++++++++++++++-------
 perl/Git.pm               |   20 +++++++
 3 files changed, 134 insertions(+), 20 deletions(-)
Show changes to 3 files +134 −20

Documentation/config.txt, git-add--interactive.perl, perl/Git.pm

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 72a33e9..c94f252 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -391,6 +391,19 @@ color.diff.<slot>::
 	whitespace).  The values of these variables may be specified as
 	in color.branch.<slot>.
 
+color.interactive::
+	When true (or `always`), always use colors in `git add
+	--interactive`.  When false (or `never`), never.  When set to
+	`auto`, use colors only when the output is to the
+	terminal. Defaults to false.
+
+color.interactive.<slot>::
+	Use customized color for `git add --interactive`
+	output. `<slot>` may be `prompt`, `header`, or `help`, for
+	three distinct types of normal output from interactive
+	programs.  The values of these variables may be specified as
+	in color.branch.<slot>.
+
 color.pager::
 	A boolean to enable/disable colored output when the pager is in
 	use (default is true).
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 335c2c6..3bcccfb 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -1,6 +1,57 @@
 #!/usr/bin/perl -w
 
 use strict;
+use Git;
+
+# Prompt colors:
+my ($use_color, $prompt_color, $header_color, $help_color, $normal_color);
+# Diff colors:
+my ($diff_use_color, $new_color, $old_color, $fraginfo_color,
+    $metainfo_color, $whitespace_color);
+my $color_config = qx(git config --get color.interactive);
+if ($color_config=~/true|always/ || -t STDOUT && $color_config=~/auto/) {
+	if (!$@) {
+		$use_color = 1;
+		# Set interactive colors:
+
+		# Grab the 3 main colors in git color string format, with sane
+		# (visible) defaults:
+		my $repo = Git->repository();
+		$prompt_color = $repo->get_color("color.interactive.prompt", "bold blue");
+		$header_color = $repo->get_color("color.interactive.header", "bold");
+		$help_color = $repo->get_color("color.interactive.help", "red bold");
+		$normal_color = $repo->get_color("", "reset");
+
+		# Do we also set diff colors?
+		my $diff_colors = Git::config($repo, "color.diff");
+		if ($diff_colors =~ /true/ ||
+		    (-t STDOUT && $diff_colors =~ /auto/)) {
+			$diff_use_color = 1;
+			$new_color = $repo->get_color("color.diff.new", "green");
+			$old_color = $repo->get_color("color.diff.old", "red");
+			$fraginfo_color = $repo->get_color("color.diff.frag", "cyan");
+			$metainfo_color = $repo->get_color("color.diff.meta", "bold");
+			$whitespace_color = $repo->get_color("color.diff.whitespace", "normal red");
+		}
+	}
+}
+
+sub colored {
+	my $color = shift;
+	my $string = join("", @_);
+
+	if ($use_color) {
+		# Put a color code at the beginning of each line, a reset at the end
+		# color after newlines that are not at the end of the string
+		$string =~ s/(\n+)(.)/$1$color$2/g;
+		# reset before newlines
+		$string =~ s/(\n+)/$normal_color$1/g;
+		# codes at beginning and end (if necessary):
+		$string =~ s/^/$color/;
+		$string =~ s/$/$normal_color/ unless $string =~ /\n$/;
+	}
+	return $string;
+}
 
 # command line options
 my $patch_mode;
@@ -246,10 +297,20 @@ sub is_valid_prefix {
 sub highlight_prefix {
 	my $prefix = shift;
 	my $remainder = shift;
-	return $remainder unless defined $prefix;
-	return is_valid_prefix($prefix) ?
-	    "[$prefix]$remainder" :
-	    "$prefix$remainder";
+
+	if (!defined $prefix) {
+		return $remainder;
+	}
+
+	if (!is_valid_prefix($prefix)) {
+		return "$prefix$remainder";
+	}
+
+	if (!$use_color) {
+		return "[$prefix]$remainder";
+	}
+
+	return "$prompt_color$prefix$normal_color$remainder";
 }
 
 sub list_and_choose {
@@ -266,7 +327,7 @@ sub list_and_choose {
 			if (!$opts->{LIST_FLAT}) {
 				print "     ";
 			}
-			print "$opts->{HEADER}\n";
+			print colored $header_color, "$opts->{HEADER}\n";
 		}
 		for ($i = 0; $i < @stuff; $i++) {
 			my $chosen = $chosen[$i] ? '*' : ' ';
@@ -304,7 +365,7 @@ sub list_and_choose {
 
 		return if ($opts->{LIST_ONLY});
 
-		print $opts->{PROMPT};
+		print colored $prompt_color, $opts->{PROMPT};
 		if ($opts->{SINGLETON}) {
 			print "> ";
 		}
@@ -371,7 +432,7 @@ sub list_and_choose {
 }
 
 sub singleton_prompt_help_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 Prompt help:
 1          - select a numbered item
 foo        - select item based on unique prefix
@@ -380,7 +441,7 @@ EOF
 }
 
 sub prompt_help_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 Prompt help:
 1          - select a single item
 3-5        - select a range of items
@@ -477,6 +538,31 @@ sub parse_diff {
 	return @hunk;
 }
 
+sub colored_diff_hunk {
+	my ($text) = @_;
+	# return the text, so that it can be passed to print()
+	my @ret;
+	for (@$text) {
+		if (!$diff_use_color) {
+			push @ret, $_;
+			next;
+		}
+
+		if (/^\+/) {
+			push @ret, colored($new_color, $_);
+		} elsif (/^\-/) {
+			push @ret, colored($old_color, $_);
+		} elsif (/^\@/) {
+			push @ret, colored($fraginfo_color, $_);
+		} elsif (/^ /) {
+			push @ret, colored($normal_color, $_);
+		} else {
+			push @ret, colored($metainfo_color, $_);
+		}
+	}
+	return @ret;
+}
+
 sub hunk_splittable {
 	my ($text) = @_;
 
@@ -671,7 +757,7 @@ sub coalesce_overlapping_hunks {
 }
 
 sub help_patch_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 y - stage this hunk
 n - do not stage this hunk
 a - stage this and all the remaining hunks in the file
@@ -710,9 +796,7 @@ sub patch_update_file {
 	my ($ix, $num);
 	my $path = shift;
 	my ($head, @hunk) = parse_diff($path);
-	for (@{$head->{TEXT}}) {
-		print;
-	}
+	print colored_diff_hunk($head->{TEXT});
 	$num = scalar @hunk;
 	$ix = 0;
 
@@ -754,10 +838,8 @@ sub patch_update_file {
 		if (hunk_splittable($hunk[$ix]{TEXT})) {
 			$other .= '/s';
 		}
-		for (@{$hunk[$ix]{TEXT}}) {
-			print;
-		}
-		print "Stage this hunk [y/n/a/d$other/?]? ";
+		print colored_diff_hunk($hunk[$ix]{TEXT});
+		print colored $prompt_color, "Stage this hunk [y/n/a/d$other/?]? ";
 		my $line = <STDIN>;
 		if ($line) {
 			if ($line =~ /^y/i) {
@@ -811,7 +893,7 @@ sub patch_update_file {
 			elsif ($other =~ /s/ && $line =~ /^s/) {
 				my @split = split_hunk($hunk[$ix]{TEXT});
 				if (1 < @split) {
-					print "Split into ",
+					print colored $header_color, "Split into ",
 					scalar(@split), " hunks.\n";
 				}
 				splice(@hunk, $ix, 1,
@@ -894,8 +976,7 @@ sub diff_cmd {
 				     HEADER => $status_head, },
 				   @mods);
 	return if (!@them);
-	system(qw(git diff-index -p --cached HEAD --),
-	       map { $_->{VALUE} } @them);
+	system(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);
 }
 
 sub quit_cmd {
@@ -904,7 +985,7 @@ sub quit_cmd {
 }
 
 sub help_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 status        - show paths with changes
 update        - add working tree state to the staged set of changes
 revert        - revert staged set of changes back to the HEAD version
diff --git a/perl/Git.pm b/perl/Git.pm
index 7468460..0f7156e 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -581,6 +581,26 @@ sub config_int {
 	};
 }
 
+=item get_color ( SLOT, COLOR )
+
+Finds color for SLOT from the configuration, while defaulting to COLOR,
+and returns the ANSI color escape sequence:
+
+	print $repo->get_color("color.interactive.prompt", "underline blue white");
+	print "some text";
+	print $repo->get_color("", "normal");
+
+=cut
+
+sub get_color {
+	my ($self, $slot, $default) = @_;
+	my $color = $self->command_oneline('config', '--get-color', $slot, $default);
+	if (!defined $color) {
+		$color = "";
+	}
+	return $color;
+}
+
 =item ident ( TYPE | IDENTSTR )
 
 =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )
-- 
1.5.3.7-2134-g53f9
Johannes Sixt· Dec 5, 2007, 12:21 UTC · re: Junio C Hamano · lore

Re: [PATCH] Color support for "git-add -i"

Junio C Hamano schrieb:
Show 5 quoted lines
> +color.interactive::
> +	When true (or `always`), always use colors in `git add
> +	--interactive`.  When false (or `never`), never.  When set to
> +	`auto`, use colors only when the output is to the
> +	terminal. Defaults to false.

Any particular reason why color.interactive = true should be different from color.diff = true? See 57f2b842 ("color.diff = true" is not "always" anymore)

-- Hannes
Wincent Colaiuta· Dec 5, 2007, 13:52 UTC · re: Johannes Sixt · lore

Re: [PATCH] Color support for "git-add -i"

El 5/12/2007, a las 13:21, Johannes Sixt escribió:
Show 11 quoted lines
> Junio C Hamano schrieb:
>> +color.interactive::
>> +	When true (or `always`), always use colors in `git add
>> +	--interactive`.  When false (or `never`), never.  When set to
>> +	`auto`, use colors only when the output is to the
>> +	terminal. Defaults to false.
>
> Any particular reason why color.interactive = true should be  
> different from
> color.diff = true? See 57f2b842 ("color.diff = true" is not "always"  
> anymore)

I wonder when you'd ever run an interactive command and not be in a terminal? ie. it doesn't make much sense to ever do "git add -i > foo", except perhaps from the test suite.

Notwithstanding, consistency for the sake of consistency is probably a good thing.

Cheers, Wincent

Junio C Hamano· Dec 5, 2007, 19:46 UTC · re: Johannes Sixt · lore

Re: [PATCH] Color support for "git-add -i"

Johannes Sixt <j.sixt@viscovery.net> writes:
Show 9 quoted lines
> Junio C Hamano schrieb:
>> +color.interactive::
>> +	When true (or `always`), always use colors in `git add
>> +	--interactive`.  When false (or `never`), never.  When set to
>> +	`auto`, use colors only when the output is to the
>> +	terminal. Defaults to false.
>
> Any particular reason why color.interactive = true should be different from
> color.diff = true? See 57f2b842 ("color.diff = true" is not "always" anymore)
Leftover from the original series.  Thanks for noticing.

We will probably want that "git config --colorbool" thing we discussed earlier.

Junio C Hamano· Dec 6, 2007, 02:05 UTC · re: Johannes Sixt · lore

[PATCH 1/3] Documentation: color.* = true means "auto"

We forgot to document the earlier sanity-fix.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/config.txt |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)
Show changes to Documentation/config.txt +7 −7
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 72a33e9..0e45ec5 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -359,8 +359,8 @@ clean.requireForce::
 
 color.branch::
 	A boolean to enable/disable color in the output of
-	gitlink:git-branch[1]. May be set to `true` (or `always`),
-	`false` (or `never`) or `auto`, in which case colors are used
+	gitlink:git-branch[1]. May be set to `always`,
+	`false` (or `never`) or `auto` (or `true`), in which case colors are used
 	only when the output is to a terminal. Defaults to false.
 
 color.branch.<slot>::
@@ -378,9 +378,9 @@ second is the background.  The position of the attribute, if any,
 doesn't matter.
 
 color.diff::
-	When true (or `always`), always use colors in patch.
-	When false (or `never`), never.  When set to `auto`, use
-	colors only when the output is to the terminal.
+	When set to `always`, always use colors in patch.
+	When false (or `never`), never.  When set to `true` or `auto`, use
+	colors only when the output is to the terminal. Defaults to false.
 
 color.diff.<slot>::
 	Use customized color for diff colorization.  `<slot>` specifies
@@ -397,8 +397,8 @@ color.pager::
 
 color.status::
 	A boolean to enable/disable color in the output of
-	gitlink:git-status[1]. May be set to `true` (or `always`),
-	`false` (or `never`) or `auto`, in which case colors are used
+	gitlink:git-status[1]. May be set to `always`,
+	`false` (or `never`) or `auto` (or `true`), in which case colors are used
 	only when the output is to a terminal. Defaults to false.
 
 color.status.<slot>::
-- 
1.5.3.7-2132-gbd1cf
Junio C Hamano· Dec 6, 2007, 02:05 UTC · re: Junio C Hamano · lore

[PATCH 2/3] git config --get-colorbool

This adds an option to help scripts find out color settings from the configuration file.

    git config --get-colorbool color.diff

inspects color.diff variable, and exits with status 0 (i.e. success) if color is to be used. It exits with status 1 otherwise.

If a script wants "true"/"false" answer to the standard output of the command, it can pass an additional boolean parameter to its command line, telling if its standard output is a terminal, like this:

    git config --get-colorbool color.diff true

When called like this, the command outputs "true" to its standard output if color is to be used (i.e. "color.diff" says "always", "auto", or "true"), and "false" otherwise.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/git-config.txt |   10 ++++++++++
 builtin-branch.c             |    2 +-
 builtin-config.c             |   41 ++++++++++++++++++++++++++++++++++++++++-
 color.c                      |    6 ++++--
 color.h                      |    2 +-
 diff.c                       |    2 +-
 wt-status.c                  |    2 +-
 7 files changed, 58 insertions(+), 7 deletions(-)
Show changes to 7 files +58 −7

Documentation/git-config.txt, builtin-branch.c, builtin-config.c, color.c, color.h, diff.c, wt-status.c

diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt
index 7640450..98509b4 100644
--- a/Documentation/git-config.txt
+++ b/Documentation/git-config.txt
@@ -21,6 +21,7 @@ SYNOPSIS
 'git-config' [<file-option>] --remove-section name
 'git-config' [<file-option>] [-z|--null] -l | --list
 'git-config' [<file-option>] --get-color name [default]
+'git-config' [<file-option>] --get-colorbool name [stdout-is-tty]
 
 DESCRIPTION
 -----------
@@ -135,6 +136,15 @@ See also <<FILES>>.
 	output without getting confused e.g. by values that
 	contain line breaks.
 
+--get-colorbool name [stdout-is-tty]::
+
+	Find the color setting for `name` (e.g. `color.diff`) and output
+	"true" or "false".  `stdout-is-tty` should be either "true" or
+	"false", and is taken into account when configuration says
+	"auto".  If `stdout-is-tty` is missing, then checks the standard
+	output of the command itself, and exits with status 0 if color
+	is to be used, or exits with status 1 otherwise.
+
 --get-color name default::
 
 	Find the color configured for `name` (e.g. `color.diff.new`) and
diff --git a/builtin-branch.c b/builtin-branch.c
index c64768b..089cae5 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -65,7 +65,7 @@ static int parse_branch_color_slot(const char *var, int ofs)
 static int git_branch_config(const char *var, const char *value)
 {
 	if (!strcmp(var, "color.branch")) {
-		branch_use_color = git_config_colorbool(var, value);
+		branch_use_color = git_config_colorbool(var, value, -1);
 		return 0;
 	}
 	if (!prefixcmp(var, "color.branch.")) {
diff --git a/builtin-config.c b/builtin-config.c
index 6175dc3..d10b03f 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -3,7 +3,7 @@
 #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 | --get-color var [default]";
+"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] | --get-colorbool name [stdout-is-tty]";
 
 static char *key;
 static regex_t *key_regexp;
@@ -208,6 +208,43 @@ static int get_color(int argc, const char **argv)
 	return 0;
 }
 
+static int stdout_is_tty;
+static int get_colorbool_found;
+static int git_get_colorbool_config(const char *var, const char *value)
+{
+	if (!strcmp(var, get_color_slot))
+		get_colorbool_found =
+			git_config_colorbool(var, value, stdout_is_tty);
+	return 0;
+}
+
+static int get_colorbool(int argc, const char **argv)
+{
+	/*
+	 * git config --get-colorbool <slot> [<stdout-is-tty>]
+	 *
+	 * returns "true" or "false" depending on how <slot>
+	 * is configured.
+	 */
+
+	if (argc == 2)
+		stdout_is_tty = git_config_bool("command line", argv[1]);
+	else if (argc == 1)
+		stdout_is_tty = isatty(1);
+	else
+		usage(git_config_set_usage);
+	get_colorbool_found = 0;
+	get_color_slot = argv[0];
+	git_config(git_get_colorbool_config);
+
+	if (argc == 1) {
+		return get_colorbool_found ? 0 : 1;
+	} else {
+		printf("%s\n", get_colorbool_found ? "true" : "false");
+		return 0;
+	}
+}
+
 int cmd_config(int argc, const char **argv, const char *prefix)
 {
 	int nongit = 0;
@@ -283,6 +320,8 @@ int cmd_config(int argc, const char **argv, const char *prefix)
 			return 0;
 		} else if (!strcmp(argv[1], "--get-color")) {
 			return get_color(argc-2, argv+2);
+		} else if (!strcmp(argv[1], "--get-colorbool")) {
+			return get_colorbool(argc-2, argv+2);
 		} else
 			break;
 		argc--;
diff --git a/color.c b/color.c
index 97cfbda..7bd424a 100644
--- a/color.c
+++ b/color.c
@@ -116,7 +116,7 @@ bad:
 	die("bad config value '%s' for variable '%s'", value, var);
 }
 
-int git_config_colorbool(const char *var, const char *value)
+int git_config_colorbool(const char *var, const char *value, int stdout_is_tty)
 {
 	if (value) {
 		if (!strcasecmp(value, "never"))
@@ -133,7 +133,9 @@ int git_config_colorbool(const char *var, const char *value)
 
 	/* any normal truth value defaults to 'auto' */
  auto_color:
-	if (isatty(1) || (pager_in_use && pager_use_color)) {
+	if (stdout_is_tty < 0)
+		stdout_is_tty = isatty(1);
+	if (stdout_is_tty || (pager_in_use && pager_use_color)) {
 		char *term = getenv("TERM");
 		if (term && strcmp(term, "dumb"))
 			return 1;
diff --git a/color.h b/color.h
index 6809800..ff63513 100644
--- a/color.h
+++ b/color.h
@@ -4,7 +4,7 @@
 /* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */
 #define COLOR_MAXLEN 24
 
-int git_config_colorbool(const char *var, const char *value);
+int git_config_colorbool(const char *var, const char *value, int stdout_is_tty);
 void color_parse(const char *var, const char *value, char *dst);
 int color_fprintf(FILE *fp, const char *color, const char *fmt, ...);
 int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...);
diff --git a/diff.c b/diff.c
index 6b54959..be6cf68 100644
--- a/diff.c
+++ b/diff.c
@@ -146,7 +146,7 @@ int git_diff_ui_config(const char *var, const char *value)
 		return 0;
 	}
 	if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
-		diff_use_color_default = git_config_colorbool(var, value);
+		diff_use_color_default = git_config_colorbool(var, value, -1);
 		return 0;
 	}
 	if (!strcmp(var, "diff.renames")) {
diff --git a/wt-status.c b/wt-status.c
index d35386d..02dbb75 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -391,7 +391,7 @@ void wt_status_print(struct wt_status *s)
 int git_status_config(const char *k, const char *v)
 {
 	if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
-		wt_status_use_color = git_config_colorbool(k, v);
+		wt_status_use_color = git_config_colorbool(k, v, -1);
 		return 0;
 	}
 	if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
-- 
1.5.3.7-2132-gbd1cf
Junio C Hamano· Dec 6, 2007, 02:05 UTC · re: Junio C Hamano · lore

[PATCH 3/3] Color support for "git-add -i"

This is mostly lifted from earlier series by Dan Zwell, but updated to use "git config --get-color" and "git config --get-colorbool" to make it simpler and more consistent with commands written in C.

A new configuration color.interactive variable is like color.diff and color.status, and controls if "git-add -i" uses color.

A set of configuration variables, color.interactive.<slot>, are used to define what color is used for the prompt, header, and help text.

For perl scripts, Git.pm provides $repo->get_color() method, which takes the slot name and the default color, and returns the terminal escape sequence to color the output text. $repo->get_colorbool() method can be used to check if color is set to be used for a given operation.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 Documentation/config.txt  |   12 +++++
 git-add--interactive.perl |  119 +++++++++++++++++++++++++++++++++++++--------
 perl/Git.pm               |   35 +++++++++++++
 3 files changed, 146 insertions(+), 20 deletions(-)
Show changes to 3 files +146 −20

Documentation/config.txt, git-add--interactive.perl, perl/Git.pm

diff --git a/Documentation/config.txt b/Documentation/config.txt
index 0e45ec5..736fcd7 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -391,6 +391,18 @@ color.diff.<slot>::
 	whitespace).  The values of these variables may be specified as
 	in color.branch.<slot>.
 
+color.interactive::
+	When set to `always`, always use colors in `git add --interactive`.
+	When false (or `never`), never.  When set to `true` or `auto`, use
+	colors only when the output is to the terminal. Defaults to false.
+
+color.interactive.<slot>::
+	Use customized color for `git add --interactive`
+	output. `<slot>` may be `prompt`, `header`, or `help`, for
+	three distinct types of normal output from interactive
+	programs.  The values of these variables may be specified as
+	in color.branch.<slot>.
+
 color.pager::
 	A boolean to enable/disable colored output when the pager is in
 	use (default is true).
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 335c2c6..1019a72 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -1,6 +1,55 @@
 #!/usr/bin/perl -w
 
 use strict;
+use Git;
+
+# Prompt colors:
+my ($prompt_color, $header_color, $help_color, $normal_color);
+# Diff colors:
+my ($new_color, $old_color, $fraginfo_color, $metainfo_color, $whitespace_color);
+
+my ($use_color, $diff_use_color);
+my $repo = Git->repository();
+
+$use_color = $repo->get_colorbool('color.interactive');
+
+if ($use_color) {
+	# Set interactive colors:
+
+	# Grab the 3 main colors in git color string format, with sane
+	# (visible) defaults:
+	$prompt_color = $repo->get_color("color.interactive.prompt", "bold blue");
+	$header_color = $repo->get_color("color.interactive.header", "bold");
+	$help_color = $repo->get_color("color.interactive.help", "red bold");
+	$normal_color = $repo->get_color("", "reset");
+
+	# Do we also set diff colors?
+	$diff_use_color = $repo->get_colorbool('color.diff');
+	if ($diff_use_color) {
+		$new_color = $repo->get_color("color.diff.new", "green");
+		$old_color = $repo->get_color("color.diff.old", "red");
+		$fraginfo_color = $repo->get_color("color.diff.frag", "cyan");
+		$metainfo_color = $repo->get_color("color.diff.meta", "bold");
+		$whitespace_color = $repo->get_color("color.diff.whitespace", "normal red");
+	}
+}
+
+sub colored {
+	my $color = shift;
+	my $string = join("", @_);
+
+	if ($use_color) {
+		# Put a color code at the beginning of each line, a reset at the end
+		# color after newlines that are not at the end of the string
+		$string =~ s/(\n+)(.)/$1$color$2/g;
+		# reset before newlines
+		$string =~ s/(\n+)/$normal_color$1/g;
+		# codes at beginning and end (if necessary):
+		$string =~ s/^/$color/;
+		$string =~ s/$/$normal_color/ unless $string =~ /\n$/;
+	}
+	return $string;
+}
 
 # command line options
 my $patch_mode;
@@ -246,10 +295,20 @@ sub is_valid_prefix {
 sub highlight_prefix {
 	my $prefix = shift;
 	my $remainder = shift;
-	return $remainder unless defined $prefix;
-	return is_valid_prefix($prefix) ?
-	    "[$prefix]$remainder" :
-	    "$prefix$remainder";
+
+	if (!defined $prefix) {
+		return $remainder;
+	}
+
+	if (!is_valid_prefix($prefix)) {
+		return "$prefix$remainder";
+	}
+
+	if (!$use_color) {
+		return "[$prefix]$remainder";
+	}
+
+	return "$prompt_color$prefix$normal_color$remainder";
 }
 
 sub list_and_choose {
@@ -266,7 +325,7 @@ sub list_and_choose {
 			if (!$opts->{LIST_FLAT}) {
 				print "     ";
 			}
-			print "$opts->{HEADER}\n";
+			print colored $header_color, "$opts->{HEADER}\n";
 		}
 		for ($i = 0; $i < @stuff; $i++) {
 			my $chosen = $chosen[$i] ? '*' : ' ';
@@ -304,7 +363,7 @@ sub list_and_choose {
 
 		return if ($opts->{LIST_ONLY});
 
-		print $opts->{PROMPT};
+		print colored $prompt_color, $opts->{PROMPT};
 		if ($opts->{SINGLETON}) {
 			print "> ";
 		}
@@ -371,7 +430,7 @@ sub list_and_choose {
 }
 
 sub singleton_prompt_help_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 Prompt help:
 1          - select a numbered item
 foo        - select item based on unique prefix
@@ -380,7 +439,7 @@ EOF
 }
 
 sub prompt_help_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 Prompt help:
 1          - select a single item
 3-5        - select a range of items
@@ -477,6 +536,31 @@ sub parse_diff {
 	return @hunk;
 }
 
+sub colored_diff_hunk {
+	my ($text) = @_;
+	# return the text, so that it can be passed to print()
+	my @ret;
+	for (@$text) {
+		if (!$diff_use_color) {
+			push @ret, $_;
+			next;
+		}
+
+		if (/^\+/) {
+			push @ret, colored($new_color, $_);
+		} elsif (/^\-/) {
+			push @ret, colored($old_color, $_);
+		} elsif (/^\@/) {
+			push @ret, colored($fraginfo_color, $_);
+		} elsif (/^ /) {
+			push @ret, colored($normal_color, $_);
+		} else {
+			push @ret, colored($metainfo_color, $_);
+		}
+	}
+	return @ret;
+}
+
 sub hunk_splittable {
 	my ($text) = @_;
 
@@ -671,7 +755,7 @@ sub coalesce_overlapping_hunks {
 }
 
 sub help_patch_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 y - stage this hunk
 n - do not stage this hunk
 a - stage this and all the remaining hunks in the file
@@ -710,9 +794,7 @@ sub patch_update_file {
 	my ($ix, $num);
 	my $path = shift;
 	my ($head, @hunk) = parse_diff($path);
-	for (@{$head->{TEXT}}) {
-		print;
-	}
+	print colored_diff_hunk($head->{TEXT});
 	$num = scalar @hunk;
 	$ix = 0;
 
@@ -754,10 +836,8 @@ sub patch_update_file {
 		if (hunk_splittable($hunk[$ix]{TEXT})) {
 			$other .= '/s';
 		}
-		for (@{$hunk[$ix]{TEXT}}) {
-			print;
-		}
-		print "Stage this hunk [y/n/a/d$other/?]? ";
+		print colored_diff_hunk($hunk[$ix]{TEXT});
+		print colored $prompt_color, "Stage this hunk [y/n/a/d$other/?]? ";
 		my $line = <STDIN>;
 		if ($line) {
 			if ($line =~ /^y/i) {
@@ -811,7 +891,7 @@ sub patch_update_file {
 			elsif ($other =~ /s/ && $line =~ /^s/) {
 				my @split = split_hunk($hunk[$ix]{TEXT});
 				if (1 < @split) {
-					print "Split into ",
+					print colored $header_color, "Split into ",
 					scalar(@split), " hunks.\n";
 				}
 				splice(@hunk, $ix, 1,
@@ -894,8 +974,7 @@ sub diff_cmd {
 				     HEADER => $status_head, },
 				   @mods);
 	return if (!@them);
-	system(qw(git diff-index -p --cached HEAD --),
-	       map { $_->{VALUE} } @them);
+	system(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them);
 }
 
 sub quit_cmd {
@@ -904,7 +983,7 @@ sub quit_cmd {
 }
 
 sub help_cmd {
-	print <<\EOF ;
+	print colored $help_color, <<\EOF ;
 status        - show paths with changes
 update        - add working tree state to the staged set of changes
 revert        - revert staged set of changes back to the HEAD version
diff --git a/perl/Git.pm b/perl/Git.pm
index 7468460..a2812ea 100644
--- a/perl/Git.pm
+++ b/perl/Git.pm
@@ -581,6 +581,41 @@ sub config_int {
 	};
 }
 
+=item get_colorbool ( NAME )
+
+Finds if color should be used for NAMEd operation from the configuration,
+and returns boolean (true for "use color", false for "do not use color").
+
+=cut
+
+sub get_colorbool {
+	my ($self, $var) = @_;
+	my $stdout_to_tty = (-t STDOUT) ? "true" : "false";
+	my $use_color = $self->command_oneline('config', '--get-colorbool',
+					       $var, $stdout_to_tty);
+	return ($use_color eq 'true');
+}
+
+=item get_color ( SLOT, COLOR )
+
+Finds color for SLOT from the configuration, while defaulting to COLOR,
+and returns the ANSI color escape sequence:
+
+	print $repo->get_color("color.interactive.prompt", "underline blue white");
+	print "some text";
+	print $repo->get_color("", "normal");
+
+=cut
+
+sub get_color {
+	my ($self, $slot, $default) = @_;
+	my $color = $self->command_oneline('config', '--get-color', $slot, $default);
+	if (!defined $color) {
+		$color = "";
+	}
+	return $color;
+}
+
 =item ident ( TYPE | IDENTSTR )
 
 =item ident_person ( TYPE | IDENTSTR | IDENTARRAY )
-- 
1.5.3.7-2132-gbd1cf
Junio C Hamano· Dec 6, 2007, 02:05 UTC · re: Junio C Hamano · lore

[PATCH 0/3] Reroll colorized "git add -i"

Another try of the colorized "git add -i" series.
[PATCH 1/3] Documentation: color.* = true means "auto"

This is a documentation fix that has already been applied to 'master' (not pushed out yet as of this writing).

[PATCH 2/3] git config --get-colorbool
This allows scripts to figure out if they should use colors.
[PATCH 3/3] Color support for "git-add -i"

This is Dan's colorized git-add -i, but uses --get-color and --get-colorbool options to git-config.

Jeff King· Dec 6, 2007, 05:40 UTC · re: Junio C Hamano · lore

Re: [PATCH 3/3] Color support for "git-add -i"

On Wed, Dec 05, 2007 at 06:05:05PM -0800, Junio C Hamano wrote:
> This is mostly lifted from earlier series by Dan Zwell, but updated to
> use "git config --get-color" and "git config --get-colorbool" to make it
> simpler and more consistent with commands written in C.

Looks mostly sane, except for the colorbool issues I mentioned in response to 2/3.

Show 13 quoted lines
> diff --git a/git-add--interactive.perl b/git-add--interactive.perl
> index 335c2c6..1019a72 100755
> --- a/git-add--interactive.perl
> +++ b/git-add--interactive.perl
> [...]
> +	# Do we also set diff colors?
> +	$diff_use_color = $repo->get_colorbool('color.diff');
> +	if ($diff_use_color) {
> +		$new_color = $repo->get_color("color.diff.new", "green");
> +		$old_color = $repo->get_color("color.diff.old", "red");
> +		$fraginfo_color = $repo->get_color("color.diff.frag", "cyan");
> +		$metainfo_color = $repo->get_color("color.diff.meta", "bold");
> +		$whitespace_color = $repo->get_color("color.diff.whitespace", "normal red");
diff.color support?

BTW, I am nagging about this because we never resolved what should happen. I am fine with the answer being "we are dropping support now."

Show 16 quoted lines
> +sub colored {
> +	my $color = shift;
> +	my $string = join("", @_);
> +
> +	if ($use_color) {
> +		# Put a color code at the beginning of each line, a reset at the end
> +		# color after newlines that are not at the end of the string
> +		$string =~ s/(\n+)(.)/$1$color$2/g;
> +		# reset before newlines
> +		$string =~ s/(\n+)/$normal_color$1/g;
> +		# codes at beginning and end (if necessary):
> +		$string =~ s/^/$color/;
> +		$string =~ s/$/$normal_color/ unless $string =~ /\n$/;
> +	}
> +	return $string;
> +}

I still think this should go into Git.pm; I believe git-svn could make use of it.

Show 21 quoted lines
>  sub highlight_prefix {
>  	my $prefix = shift;
>  	my $remainder = shift;
> -	return $remainder unless defined $prefix;
> -	return is_valid_prefix($prefix) ?
> -	    "[$prefix]$remainder" :
> -	    "$prefix$remainder";
> +
> +	if (!defined $prefix) {
> +		return $remainder;
> +	}
> +
> +	if (!is_valid_prefix($prefix)) {
> +		return "$prefix$remainder";
> +	}
> +
> +	if (!$use_color) {
> +		return "[$prefix]$remainder";
> +	}
> +
> +	return "$prompt_color$prefix$normal_color$remainder";

Honestly, I find this blue+white coloring of the prefixes a bit ugly, but that is not your fault. :)

-Peff
Wincent Colaiuta· Dec 6, 2007, 19:59 UTC · re: Junio C Hamano · lore

Re: [PATCH 3/3] Color support for "git-add -i"

El 6/12/2007, a las 3:05, Junio C Hamano escribió:
Show 24 quoted lines
> +sub colored_diff_hunk {
> +	my ($text) = @_;
> +	# return the text, so that it can be passed to print()
> +	my @ret;
> +	for (@$text) {
> +		if (!$diff_use_color) {
> +			push @ret, $_;
> +			next;
> +		}
> +
> +		if (/^\+/) {
> +			push @ret, colored($new_color, $_);
> +		} elsif (/^\-/) {
> +			push @ret, colored($old_color, $_);
> +		} elsif (/^\@/) {
> +			push @ret, colored($fraginfo_color, $_);
> +		} elsif (/^ /) {
> +			push @ret, colored($normal_color, $_);
> +		} else {
> +			push @ret, colored($metainfo_color, $_);
> +		}
> +	}
> +	return @ret;
> +}

My one concern here is that as Git's awareness of whitespace problems becomes more sophisticated it will be harder and harder to do diff colorization in a way that matches that which is performed by the builtin diff tools. Here I'm talking about the whole core.whitespace series which allows the user to define per-path attributes specifying what kinds of things are to be considered whitespace errors; so far we have three classes of error proposed as far as I know: trailing whitespace, spaces before tabs, and indents with non-tabs.

I think it's very important that "git add --interactive" be 100% consistent with the other tools here because in many cases the previewing you do during an interactive session is what you rely upon to review whether a change should be committed. In other words, you don't want to think stuff is ok because "git add --interactive" leads you to believe that it's ok when it really isn't, and you don't want to have to run "git diff" as a separate step either just to double check.

We can replicate the core.whitespace logic here but it's likely to be an error prone process as it involves repeating the same logic in two different places using two different implementations in two different languages.

What are the other options?
- Make git-add--interactive part of builtin-add so as to be able to  
use the core.whitespace code directly? (ideally yes and at some point  
in the future it seems inevitable that this will happen, but it will  
require a fair bit of work)
- Fork a second "git diff-files" process to capture the colorized  
version of the output? (may set off the "kludge" alarm)
- Something else?

Cheers, Wincent

Junio C Hamano· Dec 6, 2007, 20:18 UTC · re: Wincent Colaiuta · lore

Re: [PATCH 3/3] Color support for "git-add -i"

Wincent Colaiuta <win@wincent.com> writes:
Show 11 quoted lines
> What are the other options?
>
> - Make git-add--interactive part of builtin-add so as to be able to  
> use the core.whitespace code directly? (ideally yes and at some point  
> in the future it seems inevitable that this will happen, but it will  
> require a fair bit of work)
>
> - Fork a second "git diff-files" process to capture the colorized  
> version of the output? (may set off the "kludge" alarm)
>
> - Something else?
 - Realize that whitespace clean-up can be risky and change semantics
   depending on the material you are editing.  Do not do the clean-up
   during "add -i", but before.  IOW, add an alias that does an
   equivalent of:
	git diff HEAD >tmp
        git apply -R <tmp
        git apply --whitespace=fix <tmp
   then encourage users to clean-up their whitespace gotchas early (and
   test the result!), before even attempting to run "git add -i".
Wincent Colaiuta· Dec 7, 2007, 12:34 UTC · re: Junio C Hamano · lore

Re: [PATCH 3/3] Color support for "git-add -i"

El 6/12/2007, a las 21:18, Junio C Hamano escribió:
Show 25 quoted lines
> Wincent Colaiuta <win@wincent.com> writes:
>
>> What are the other options?
>>
>> - Make git-add--interactive part of builtin-add so as to be able to
>> use the core.whitespace code directly? (ideally yes and at some point
>> in the future it seems inevitable that this will happen, but it will
>> require a fair bit of work)
>>
>> - Fork a second "git diff-files" process to capture the colorized
>> version of the output? (may set off the "kludge" alarm)
>>
>> - Something else?
>
> - Realize that whitespace clean-up can be risky and change semantics
>   depending on the material you are editing.  Do not do the clean-up
>   during "add -i", but before.  IOW, add an alias that does an
>   equivalent of:
>
> 	git diff HEAD >tmp
>        git apply -R <tmp
>        git apply --whitespace=fix <tmp
>
>   then encourage users to clean-up their whitespace gotchas early (and
>   test the result!), before even attempting to run "git add -i".

In principle I agree with what you're saying but I think I didn't make myself clear; I wasn't talking about actually *cleaning-up* whitespace problems from inside "git add -i", I was talking about *display* of whitespace problems only. In other words, I don't want the situation where I think it's ok to stage a hunk only because I mistakenly think it's free of whitespace problems. In other words, if one part of Git ("git diff") says the diff is "this" and another part ("git add -i") says the diff is "that" and there's a discrepancy, then that sounds like a bug to me.

Seeing as speed is not a concern here (when displaying diffs the bottleneck is really how fast the user can read, not how fast git emits the text), correctness is important, and git-add--interactive will eventually become part of builtin-add anyway, I personally think the optimum solution is this one: run the diff tools twice, once without color and once with; the former is used for internal processing as before and the later is used for display only. This approach has the advantage that the whitespace colorization provided by "git diff-files" can evolve and become more sophisticated (per-path attributes etc) and "git add -i" will automatically benefit from it.

But I wanted to throw the question out there for input first, in any case, I have a patch implementing my proposal and I'll send it out in a minute.

Cheers, Wincent

Jeff King· Dec 6, 2007, 05:30 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/3] git config --get-colorbool

[Eric Wong cc'd because of git-svn relevance]
On Wed, Dec 05, 2007 at 06:05:04PM -0800, Junio C Hamano wrote:
Show 7 quoted lines
> This adds an option to help scripts find out color settings from
> the configuration file.
> 
>     git config --get-colorbool color.diff
> 
> inspects color.diff variable, and exits with status 0 (i.e. success) if
> color is to be used.  It exits with status 1 otherwise.

There is no way to differentiate between "do not use color" and "no value found". This makes it impossible to use this to implement the required "try color.diff, fallback to diff.color" behavior.

We could simply make it
  git config --get-colorbool diff

which would check both (and when diff.color support is finally dropped, just remove it from there).

git-svn should probably be moved to this interface (it still has the color.diff == true means "always" behavior), but it can't be until the fallback behavior is implemented.

Also, your patch doesn't seem to implement the color.pager/pager.color behavior, either (which is probably not important for git-add -i, but is used by git-svn).

Anyway, below is a totally untested (I don't even have svn installed, but it passes perl -wc!) patch for git-svn to use the new "true means auto" behavior for color.diff. It would be nice to replace this with a working --get-colorbool, but we should at least unify the behavior before v1.5.4.

-Peff
---
Show changes to git-svn.perl +7 −5
diff --git a/git-svn.perl b/git-svn.perl
index 9f884eb..71f6e93 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -3979,7 +3979,12 @@ sub log_use_color {
 		$dc = `git-config --get $dcvar`;
 	}
 	chomp($dc);
-	if ($dc eq 'auto') {
+	return 0 if $dc eq 'never';
+	return 1 if $dc eq 'always';
+	if ($dc ne 'auto') {
+		chomp($dc = `git-config --bool --get $dcvar`);
+	}
+	if ($dc eq 'auto' || $dc eq 'true') {
 		my $pc;
 		$pc = `git-config --get color.pager`;
 		if ($pc eq '') {
@@ -3998,10 +4003,7 @@ sub log_use_color {
 		}
 		return 0;
 	}
-	return 0 if $dc eq 'never';
-	return 1 if $dc eq 'always';
-	chomp($dc = `git-config --bool --get $dcvar`);
-	return ($dc eq 'true');
+	return 0;
 }
 
 sub git_svn_log_cmd {
Jeff King· Dec 6, 2007, 05:35 UTC · re: Jeff King · lore

Re: [PATCH 2/3] git config --get-colorbool

On Thu, Dec 06, 2007 at 12:30:59AM -0500, Jeff King wrote:
> Also, your patch doesn't seem to implement the color.pager/pager.color
> behavior, either (which is probably not important for git-add -i, but is
> used by git-svn).

Oops, maybe I should actually read your patch more carefully before criticizing. I see that you do handle pager_use_color in git_config_colorbool, but I think that for --get-colorbool usage, pager_in_use is going to be useless (wow, three forms of "use" in one clause).

-Peff
Junio C Hamano· Dec 6, 2007, 06:12 UTC · re: Jeff King · lore

Re: [PATCH 2/3] git config --get-colorbool

Jeff King <peff@peff.net> writes:
Show 22 quoted lines
> [Eric Wong cc'd because of git-svn relevance]
>
> On Wed, Dec 05, 2007 at 06:05:04PM -0800, Junio C Hamano wrote:
>
>> This adds an option to help scripts find out color settings from
>> the configuration file.
>> 
>>     git config --get-colorbool color.diff
>> 
>> inspects color.diff variable, and exits with status 0 (i.e. success) if
>> color is to be used.  It exits with status 1 otherwise.
>
> There is no way to differentiate between "do not use color" and "no
> value found". This makes it impossible to use this to implement the
> required "try color.diff, fallback to diff.color" behavior.
>
> We could simply make it
>
>   git config --get-colorbool diff
>
> which would check both (and when diff.color support is finally dropped,
> just remove it from there).

I thought about this a bit and thought that it would probably be a good workaround to teach "--get-colorbool that diff.color is a deprecated synonym to color.diff, like this.

-- >8 -- config --get-colorbool: diff.color is a deprecated synonym to color.diff

The applications can ask for color.diff but the configuration of old timer users can still instruct it to use color with diff.color this way.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin-config.c |   18 ++++++++++++++++--
 1 files changed, 16 insertions(+), 2 deletions(-)
Show changes to builtin-config.c +16 −2
diff --git a/builtin-config.c b/builtin-config.c
index d10b03f..e4a12e3 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -210,11 +210,17 @@ static int get_color(int argc, const char **argv)
 
 static int stdout_is_tty;
 static int get_colorbool_found;
+static int get_diff_color_found;
 static int git_get_colorbool_config(const char *var, const char *value)
 {
-	if (!strcmp(var, get_color_slot))
+	if (!strcmp(var, get_color_slot)) {
 		get_colorbool_found =
 			git_config_colorbool(var, value, stdout_is_tty);
+	}
+	if (!strcmp(var, "diff.color")) {
+		get_diff_color_found =
+			git_config_colorbool(var, value, stdout_is_tty);
+	}
 	return 0;
 }
 
@@ -233,10 +239,18 @@ static int get_colorbool(int argc, const char **argv)
 		stdout_is_tty = isatty(1);
 	else
 		usage(git_config_set_usage);
-	get_colorbool_found = 0;
+	get_colorbool_found = -1;
+	get_diff_color_found = -1;
 	get_color_slot = argv[0];
 	git_config(git_get_colorbool_config);
 
+	if (get_colorbool_found < 0) {
+		if (!strcmp(get_color_slot, "color.diff"))
+			get_colorbool_found = get_diff_color_found;
+		if (get_colorbool_found < 0)
+			get_colorbool_found = 0;
+	}
+
 	if (argc == 1) {
 		return get_colorbool_found ? 0 : 1;
 	} else {
Jeff King· Dec 6, 2007, 06:17 UTC · re: Junio C Hamano · lore

Re: [PATCH 2/3] git config --get-colorbool

On Wed, Dec 05, 2007 at 10:12:07PM -0800, Junio C Hamano wrote:
> I thought about this a bit and thought that it would probably be a good
> workaround to teach "--get-colorbool that diff.color is a deprecated
> synonym to color.diff, like this.

Reasonable. Technically, one is required for status.color/color.status, as well, though there are no users in git-core.

-Peff
Eric Wong· Dec 6, 2007, 07:38 UTC · re: Jeff King · lore

Re: [PATCH 2/3] git config --get-colorbool

Jeff King <peff@peff.net> wrote:
Show 36 quoted lines
> [Eric Wong cc'd because of git-svn relevance]
> 
> On Wed, Dec 05, 2007 at 06:05:04PM -0800, Junio C Hamano wrote:
> 
> > This adds an option to help scripts find out color settings from
> > the configuration file.
> > 
> >     git config --get-colorbool color.diff
> > 
> > inspects color.diff variable, and exits with status 0 (i.e. success) if
> > color is to be used.  It exits with status 1 otherwise.
> 
> There is no way to differentiate between "do not use color" and "no
> value found". This makes it impossible to use this to implement the
> required "try color.diff, fallback to diff.color" behavior.
> 
> We could simply make it
> 
>   git config --get-colorbool diff
> 
> which would check both (and when diff.color support is finally dropped,
> just remove it from there).
> 
> git-svn should probably be moved to this interface (it still has the
> color.diff == true means "always" behavior), but it can't be until the
> fallback behavior is implemented.
> 
> Also, your patch doesn't seem to implement the color.pager/pager.color
> behavior, either (which is probably not important for git-add -i, but is
> used by git-svn).
> 
> Anyway, below is a totally untested (I don't even have svn installed,
> but it passes perl -wc!) patch for git-svn to use the new "true means
> auto" behavior for color.diff. It would be nice to replace this with
> a working --get-colorbool, but we should at least unify the behavior
> before v1.5.4.
Hi Jeff,

I completely agree that the color behavior should be consistent across git-*. So I'd like to just be able to just use --get-colorbool in git-svn.

Your patch seems to do what it says it does, though.
Show 34 quoted lines
> -Peff
> 
> ---
> diff --git a/git-svn.perl b/git-svn.perl
> index 9f884eb..71f6e93 100755
> --- a/git-svn.perl
> +++ b/git-svn.perl
> @@ -3979,7 +3979,12 @@ sub log_use_color {
>  		$dc = `git-config --get $dcvar`;
>  	}
>  	chomp($dc);
> -	if ($dc eq 'auto') {
> +	return 0 if $dc eq 'never';
> +	return 1 if $dc eq 'always';
> +	if ($dc ne 'auto') {
> +		chomp($dc = `git-config --bool --get $dcvar`);
> +	}
> +	if ($dc eq 'auto' || $dc eq 'true') {
>  		my $pc;
>  		$pc = `git-config --get color.pager`;
>  		if ($pc eq '') {
> @@ -3998,10 +4003,7 @@ sub log_use_color {
>  		}
>  		return 0;
>  	}
> -	return 0 if $dc eq 'never';
> -	return 1 if $dc eq 'always';
> -	chomp($dc = `git-config --bool --get $dcvar`);
> -	return ($dc eq 'true');
> +	return 0;
>  }
>  
>  sub git_svn_log_cmd {
> -
-- 
Eric Wong
Wincent Colaiuta· Dec 5, 2007, 13:55 UTC · re: Junio C Hamano · lore

Re: [PATCH] Color support for "git-add -i"

El 5/12/2007, a las 11:59, Junio C Hamano escribió:
> This is mostly lifted from earlier series by Dan Zwell, but updated to
> use "git config --get-color" to make it simpler and more consistent  
> with
> commands written in C.

Tested here and seems to work well. This is a nice little bit of usability polish.

Cheers, Wincent

← back to recent threads