Add an optional argument for --color options

Make git-branch, git-show-branch, git-grep, and all the diff-based
programs accept an optional argument <when> for --color.  The argument
is a colorbool: "always", "never", or "auto".  If no argument is given,
"always" is used;  --no-color is an alias for --color=never.  This makes
the command-line interface consistent with other GNU tools, such as `ls'
and `grep', and with the git-config color options.  Note that, without
an argument, --color and --no-color work exactly as before.

To implement this, two internal changes were made:

1. Allow the first argument of git_config_colorbool() to be NULL,
   in which case it returns -1 if the argument isn't "always", "never",
   or "auto".

2. Add OPT_COLOR_FLAG(), OPT__COLOR(), and parse_opt_color_flag_cb()
   to the option parsing library.  The callback uses
   git_config_colorbool(), so color.h is now a dependency
   of parse-options.c.

Signed-off-by: Mark Lodato <lodatom@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Mark Lodato 2010-02-16 23:55:58 -05:00 committed by Junio C Hamano
parent e923eaeb90
commit 73e9da0196
12 changed files with 66 additions and 11 deletions

View File

@ -117,12 +117,14 @@ any of those replacements occurred.
option and lists the commits in that commit range like the 'summary'
option of linkgit:git-submodule[1] does.
--color::
--color[=<when>]::
Show colored diff.
The value must be always (the default), never, or auto.
--no-color::
Turn off colored diff, even when the configuration file
gives the default to color output.
Same as `--color=never`.
--color-words[=<regex>]::
Show colored word diff, i.e., color words which have changed.

View File

@ -8,7 +8,7 @@ git-branch - List, create, or delete branches
SYNOPSIS
--------
[verse]
'git branch' [--color | --no-color] [-r | -a]
'git branch' [--color[=<when>] | --no-color] [-r | -a]
[-v [--abbrev=<length> | --no-abbrev]]
[(--merged | --no-merged | --contains) [<commit>]]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
@ -84,12 +84,14 @@ OPTIONS
-M::
Move/rename a branch even if the new branch name already exists.
--color::
--color[=<when>]::
Color branches to highlight current, local, and remote branches.
The value must be always (the default), never, or auto.
--no-color::
Turn off branch colors, even when the configuration file gives the
default to color output.
Same as `--color=never`.
-r::
List or delete (if used with -d) the remote-tracking branches.

View File

@ -18,7 +18,7 @@ SYNOPSIS
[-z | --null]
[-c | --count] [--all-match] [-q | --quiet]
[--max-depth <depth>]
[--color | --no-color]
[--color[=<when>] | --no-color]
[-A <post-context>] [-B <pre-context>] [-C <context>]
[-f <file>] [-e] <pattern>
[--and|--or|--not|(|)|-e <pattern>...] [<tree>...]
@ -111,12 +111,14 @@ OPTIONS
Instead of showing every matched line, show the number of
lines that match.
--color::
--color[=<when>]::
Show colored matches.
The value must be always (the default), never, or auto.
--no-color::
Turn off match highlighting, even when the configuration file
gives the default to color output.
Same as `--color=never`.
-[ABC] <context>::
Show `context` trailing (`A` -- after), or leading (`B`

View File

@ -9,7 +9,7 @@ SYNOPSIS
--------
[verse]
'git show-branch' [-a|--all] [-r|--remotes] [--topo-order | --date-order]
[--current] [--color | --no-color] [--sparse]
[--current] [--color[=<when>] | --no-color] [--sparse]
[--more=<n> | --list | --independent | --merge-base]
[--no-name | --sha1-name] [--topics]
[<rev> | <glob>]...
@ -117,13 +117,15 @@ OPTIONS
When no explicit <ref> parameter is given, it defaults to the
current branch (or `HEAD` if it is detached).
--color::
--color[=<when>]::
Color the status sign (one of these: `*` `!` `+` `-`) of each commit
corresponding to the branch it's in.
The value must be always (the default), never, or auto.
--no-color::
Turn off colored output, even when the configuration file gives the
default to color output.
Same as `--color=never`.
Note that --more, --list, --independent and --merge-base options
are mutually exclusive.

View File

@ -115,6 +115,9 @@ There are some macros to easily define options:
`OPT__ABBREV(&int_var)`::
Add `\--abbrev[=<n>]`.
`OPT__COLOR(&int_var, description)`::
Add `\--color[=<when>]` and `--no-color`.
`OPT__DRY_RUN(&int_var)`::
Add `-n, \--dry-run`.
@ -183,6 +186,15 @@ There are some macros to easily define options:
arguments. Short options that happen to be digits take
precedence over it.
`OPT_COLOR_FLAG(short, long, &int_var, description)`::
Introduce an option that takes an optional argument that can
have one of three values: "always", "never", or "auto". If the
argument is not given, it defaults to "always". The `--no-` form
works like `--long=never`; it cannot take an argument. If
"always", set `int_var` to 1; if "never", set `int_var` to 0; if
"auto", set `int_var` to 1 if stdout is a tty or a pager,
0 otherwise.
The last element of the array must be `OPT_END()`.

View File

@ -610,7 +610,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
BRANCH_TRACK_EXPLICIT),
OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
BRANCH_TRACK_OVERRIDE),
OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
OPT__COLOR(&branch_use_color, "use colored output"),
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
REF_REMOTE_BRANCH),
{

View File

@ -782,7 +782,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
"print NUL after filenames"),
OPT_BOOLEAN('c', "count", &opt.count,
"show the number of matches instead of matching lines"),
OPT_SET_INT(0, "color", &opt.color, "highlight matches", 1),
OPT__COLOR(&opt.color, "highlight matches"),
OPT_GROUP(""),
OPT_CALLBACK('C', NULL, &opt, "n",
"show <n> context lines before and after matches",

View File

@ -6,7 +6,7 @@
#include "parse-options.h"
static const char* show_branch_usage[] = {
"git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--current] [--color | --no-color] [--sparse] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] [--topics] [<rev> | <glob>]...",
"git show-branch [-a|--all] [-r|--remotes] [--topo-order | --date-order] [--current] [--color[=<when>] | --no-color] [--sparse] [--more=<n> | --list | --independent | --merge-base] [--no-name | --sha1-name] [--topics] [<rev> | <glob>]...",
"git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]",
NULL
};
@ -661,7 +661,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
"show remote-tracking and local branches"),
OPT_BOOLEAN('r', "remotes", &all_remotes,
"show remote-tracking branches"),
OPT_BOOLEAN(0, "color", &showbranch_use_color,
OPT__COLOR(&showbranch_use_color,
"color '*!+-' corresponding to the branch"),
{ OPTION_INTEGER, 0, "more", &extra, "n",
"show <n> more commits after the common ancestor",

View File

@ -138,6 +138,9 @@ int git_config_colorbool(const char *var, const char *value, int stdout_is_tty)
goto auto_color;
}
if (!var)
return -1;
/* Missing or explicit false to turn off colorization */
if (!git_config_bool(var, value))
return 0;

9
diff.c
View File

@ -2826,6 +2826,15 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
DIFF_OPT_SET(options, FOLLOW_RENAMES);
else if (!strcmp(arg, "--color"))
DIFF_OPT_SET(options, COLOR_DIFF);
else if (!prefixcmp(arg, "--color=")) {
int value = git_config_colorbool(NULL, arg+8, -1);
if (value == 0)
DIFF_OPT_CLR(options, COLOR_DIFF);
else if (value > 0)
DIFF_OPT_SET(options, COLOR_DIFF);
else
return error("option `color' expects \"always\", \"auto\", or \"never\"");
}
else if (!strcmp(arg, "--no-color"))
DIFF_OPT_CLR(options, COLOR_DIFF);
else if (!strcmp(arg, "--color-words")) {

View File

@ -2,6 +2,7 @@
#include "parse-options.h"
#include "cache.h"
#include "commit.h"
#include "color.h"
static int parse_options_usage(const char * const *usagestr,
const struct option *opts);
@ -599,6 +600,21 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
return 0;
}
int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
int unset)
{
int value;
if (!arg)
arg = unset ? "never" : (const char *)opt->defval;
value = git_config_colorbool(NULL, arg, -1);
if (value < 0)
return opterror(opt,
"expects \"always\", \"auto\", or \"never\"", 0);
*(int *)opt->value = value;
return 0;
}
int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
int unset)
{

View File

@ -135,6 +135,10 @@ struct option {
PARSE_OPT_NOARG | PARSE_OPT_NONEG, (f) }
#define OPT_FILENAME(s, l, v, h) { OPTION_FILENAME, (s), (l), (v), \
"FILE", (h) }
#define OPT_COLOR_FLAG(s, l, v, h) \
{ OPTION_CALLBACK, (s), (l), (v), "when", (h), PARSE_OPT_OPTARG, \
parse_opt_color_flag_cb, (intptr_t)"always" }
/* parse_options() will filter out the processed options and leave the
* non-option arguments in argv[].
@ -187,6 +191,7 @@ extern int parse_options_end(struct parse_opt_ctx_t *ctx);
/*----- some often used options -----*/
extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
extern int parse_opt_color_flag_cb(const struct option *, const char *, int);
extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
extern int parse_opt_with_commit(const struct option *, const char *, int);
extern int parse_opt_tertiary(const struct option *, const char *, int);
@ -203,5 +208,7 @@ extern int parse_opt_tertiary(const struct option *, const char *, int);
{ OPTION_CALLBACK, 0, "abbrev", (var), "n", \
"use <n> digits to display SHA-1s", \
PARSE_OPT_OPTARG, &parse_opt_abbrev_cb, 0 }
#define OPT__COLOR(var, h) \
OPT_COLOR_FLAG(0, "color", (var), (h))
#endif