Merge branch 'ml/color-when'
authorJunio C Hamano <gitster@pobox.com>
Tue, 2 Mar 2010 20:44:06 +0000 (12:44 -0800)
committerJunio C Hamano <gitster@pobox.com>
Tue, 2 Mar 2010 20:44:06 +0000 (12:44 -0800)
* ml/color-when:
Add an optional argument for --color options

1  2 
Documentation/git-grep.txt
Documentation/git-show-branch.txt
builtin-grep.c
builtin-show-branch.c
diff.c
index c44724d03a60640d34963f068149a3fe6803d20e,70c7ef95f605110bbb34be48bef9f32050173e49..6305f6d82a52d7d3b9e0aac2b2712a4e91931666
@@@ -18,16 -18,16 +18,16 @@@ SYNOPSI
           [-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>...]
 -         [--] [<path>...]
 +         [--] [<pathspec>...]
  
  DESCRIPTION
  -----------
 -Look for specified patterns in the working tree files, blobs
 -registered in the index file, or given tree objects.
 +Look for specified patterns in the tracked files in the work tree, blobs
 +registered in the index file, or blobs in given tree objects.
  
  
  OPTIONS
@@@ -49,7 -49,7 +49,7 @@@
        Don't match the pattern in binary files.
  
  --max-depth <depth>::
 -      For each pathspec given on command line, descend at most <depth>
 +      For each <pathspec> given on command line, descend at most <depth>
        levels of directories. A negative value means no limit.
  
  -w::
        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`
  
  \--::
        Signals the end of options; the rest of the parameters
 -      are <path> limiters.
 +      are <pathspec> limiters.
  
 +<pathspec>...::
 +      If given, limit the search to paths matching at least one pattern.
 +      Both leading paths match and glob(7) patterns are supported.
  
  Example
  -------
  
 +git grep 'time_t' -- '*.[ch]'::
 +      Looks for `time_t` in all tracked .c and .h files in the working
 +      directory and its subdirectories.
 +
  git grep -e \'#define\' --and \( -e MAX_PATH -e PATH_MAX \)::
        Looks for a line that has `#define` and either `MAX_PATH` or
        `PATH_MAX`.
index b9c4154e7332fa59b370ce5be823a9cb6384227c,519f9e1dd76ebf7c93db3b8afb47aa57f4336903..f1499bba88028775032819708db22a3250b5b840
@@@ -9,7 -9,7 +9,7 @@@ SYNOPSI
  --------
  [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>]...
@@@ -20,8 -20,8 +20,8 @@@ DESCRIPTIO
  -----------
  
  Shows the commit ancestry graph starting from the commits named
 -with <rev>s or <globs>s (or all refs under $GIT_DIR/refs/heads
 -and/or $GIT_DIR/refs/tags) semi-visually.
 +with <rev>s or <globs>s (or all refs under refs/heads
 +and/or refs/tags) semi-visually.
  
  It cannot show more than 29 branches and commits at a time.
  
@@@ -37,8 -37,8 +37,8 @@@ OPTION
  
  <glob>::
        A glob pattern that matches branch or tag names under
 -      $GIT_DIR/refs.  For example, if you have many topic
 -      branches under $GIT_DIR/refs/heads/topic, giving
 +      refs/.  For example, if you have many topic
 +      branches under refs/heads/topic, giving
        `topic/*` would show all of them.
  
  -r::
        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.
@@@ -176,7 -178,7 +178,7 @@@ EXAMPL
  -------
  
  If you keep your primary branches immediately under
 -`$GIT_DIR/refs/heads`, and topic branches in subdirectories of
 +`refs/heads`, and topic branches in subdirectories of
  it, having the following in the configuration file may help:
  
  ------------
diff --combined builtin-grep.c
index d05107dd9f5e32be1d4d817171bf3e5845316204,00cbd90bf68bc729d9b4d1bdb2fcaa92954010f1..40b9a93127482bebf6dc8c9eb39b2104711a543a
@@@ -14,7 -14,6 +14,7 @@@
  #include "userdiff.h"
  #include "grep.h"
  #include "quote.h"
 +#include "dir.h"
  
  #ifndef NO_PTHREADS
  #include "thread-utils.h"
@@@ -409,25 -408,15 +409,25 @@@ static int pathspec_matches(const char 
        return 0;
  }
  
 +static void *lock_and_read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
 +{
 +      void *data;
 +
 +      if (use_threads) {
 +              read_sha1_lock();
 +              data = read_sha1_file(sha1, type, size);
 +              read_sha1_unlock();
 +      } else {
 +              data = read_sha1_file(sha1, type, size);
 +      }
 +      return data;
 +}
 +
  static void *load_sha1(const unsigned char *sha1, unsigned long *size,
                       const char *name)
  {
        enum object_type type;
 -      char *data;
 -
 -      read_sha1_lock();
 -      data = read_sha1_file(sha1, &type, size);
 -      read_sha1_unlock();
 +      void *data = lock_and_read_sha1_file(sha1, &type, size);
  
        if (!data)
                error("'%s': unable to read %s", name, sha1_to_hex(sha1));
@@@ -616,7 -605,10 +616,7 @@@ static int grep_tree(struct grep_opt *o
                        void *data;
                        unsigned long size;
  
 -                      read_sha1_lock();
 -                      data = read_sha1_file(entry.sha1, &type, &size);
 -                      read_sha1_unlock();
 -
 +                      data = lock_and_read_sha1_file(entry.sha1, &type, &size);
                        if (!data)
                                die("unable to read tree (%s)",
                                    sha1_to_hex(entry.sha1));
@@@ -653,24 -645,6 +653,24 @@@ static int grep_object(struct grep_opt 
        die("unable to grep from object of type %s", typename(obj->type));
  }
  
 +static int grep_directory(struct grep_opt *opt, const char **paths)
 +{
 +      struct dir_struct dir;
 +      int i, hit = 0;
 +
 +      memset(&dir, 0, sizeof(dir));
 +      setup_standard_excludes(&dir);
 +
 +      fill_directory(&dir, paths);
 +      for (i = 0; i < dir.nr; i++) {
 +              hit |= grep_file(opt, dir.entries[i]->name);
 +              if (hit && opt->status_only)
 +                      break;
 +      }
 +      free_grep_patterns(opt);
 +      return hit;
 +}
 +
  static int context_callback(const struct option *opt, const char *arg,
                            int unset)
  {
@@@ -765,12 -739,9 +765,12 @@@ int cmd_grep(int argc, const char **arg
        const char **paths = NULL;
        int i;
        int dummy;
 +      int nongit = 0, use_index = 1;
        struct option options[] = {
                OPT_BOOLEAN(0, "cached", &cached,
                        "search in index instead of in the work tree"),
 +              OPT_BOOLEAN(0, "index", &use_index,
 +                      "--no-index finds in contents not managed by git"),
                OPT_GROUP(""),
                OPT_BOOLEAN('v', "invert-match", &opt.invert,
                        "show non-matching lines"),
                        "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",
                OPT_END()
        };
  
 +      prefix = setup_git_directory_gently(&nongit);
 +
        /*
         * 'git grep -h', unlike 'git grep -h <pattern>', is a request
         * to show usage information and exit.
        opt.relative = 1;
        opt.pathname = 1;
        opt.pattern_tail = &opt.pattern_list;
 +      opt.header_tail = &opt.header_list;
        opt.regflags = REG_NEWLINE;
        opt.max_depth = -1;
  
                             PARSE_OPT_STOP_AT_NON_OPTION |
                             PARSE_OPT_NO_INTERNAL_HELP);
  
 +      if (use_index && nongit)
 +              /* die the same way as if we did it at the beginning */
 +              setup_git_directory();
 +
 +      /*
 +       * skip a -- separator; we know it cannot be
 +       * separating revisions from pathnames if
 +       * we haven't even had any patterns yet
 +       */
 +      if (argc > 0 && !opt.pattern_list && !strcmp(argv[0], "--")) {
 +              argv++;
 +              argc--;
 +      }
 +
        /* First unrecognized non-option token */
        if (argc > 0 && !opt.pattern_list) {
                append_grep_pattern(&opt, argv[0], "command line", 0,
                paths[1] = NULL;
        }
  
 +      if (!use_index) {
 +              int hit;
 +              if (cached)
 +                      die("--cached cannot be used with --no-index.");
 +              if (list.nr)
 +                      die("--no-index cannot be used with revs.");
 +              hit = grep_directory(&opt, paths);
 +              if (use_threads)
 +                      hit |= wait_all();
 +              return !hit;
 +      }
 +
        if (!list.nr) {
                int hit;
                if (!cached)
diff --combined builtin-show-branch.c
index 35a709e63066ad8bebc8a96dee0563bad43348b6,32d862ab238730643c1c3475b7b9613042cf9030..e20fcf3e935dfafb4e30f24990aa974c8b2f5927
@@@ -6,7 -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
  };
@@@ -567,7 -567,7 +567,7 @@@ static int git_show_branch_config(cons
                        return config_error_nonbool(var);
                /*
                 * default_arg is now passed to parse_options(), so we need to
 -               * mimick the real argv a bit better.
 +               * mimic the real argv a bit better.
                 */
                if (!default_num) {
                        default_alloc = 20;
@@@ -661,7 -661,7 +661,7 @@@ int cmd_show_branch(int ac, const char 
                            "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",
diff --combined diff.c
index 989dbc54cbb31c095cc45fb5bb74f62077f1c635,8f645f6f8dc7c6773af5859ceebd8ba5fdaded47..ed3e7c5aaf9cdbc76aba0b357cb001e9aba55a9b
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -2826,6 -2826,15 +2826,15 @@@ int diff_opt_parse(struct diff_options 
                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")) {
                ;
        else if (!prefixcmp(arg, "--output=")) {
                options->file = fopen(arg + strlen("--output="), "w");
 +              if (!options->file)
 +                      die_errno("Could not open '%s'", arg + strlen("--output="));
                options->close_file = 1;
        } else
                return 0;
@@@ -3644,7 -3651,7 +3653,7 @@@ static void diffcore_skip_stat_unmatch(
                struct diff_filepair *p = q->queue[i];
  
                /*
 -               * 1. Entries that come from stat info dirtyness
 +               * 1. Entries that come from stat info dirtiness
                 *    always have both sides (iow, not create/delete),
                 *    one side of the object name is unknown, with
                 *    the same mode and size.  Keep the ones that