Code

Merge branch 'ho/dirstat-by-file'
authorShawn O. Pearce <spearce@spearce.org>
Thu, 25 Sep 2008 15:41:42 +0000 (08:41 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Thu, 25 Sep 2008 15:41:42 +0000 (08:41 -0700)
* ho/dirstat-by-file:
  diff --dirstat-by-file: count changed files, not lines

1  2 
diff.c
diff.h

diff --combined diff.c
index 9053d4d1f6e886835813e8ba62a7d7767eefe1c8,2de86eb7603c1de1b5861168a7152c1f0f8cbf17..a2f4850d4fdf3758b75cc086e47e18736075c999
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -24,7 -24,6 +24,7 @@@ static int diff_suppress_blank_empty
  int diff_use_color_default = -1;
  static const char *external_diff_cmd_cfg;
  int diff_auto_refresh_index = 1;
 +static int diff_mnemonic_prefix;
  
  static char diff_colors[][COLOR_MAXLEN] = {
        "\033[m",       /* reset */
@@@ -151,10 -150,6 +151,10 @@@ int git_diff_ui_config(const char *var
                diff_auto_refresh_index = git_config_bool(var, value);
                return 0;
        }
 +      if (!strcmp(var, "diff.mnemonicprefix")) {
 +              diff_mnemonic_prefix = git_config_bool(var, value);
 +              return 0;
 +      }
        if (!strcmp(var, "diff.external"))
                return git_config_string(&external_diff_cmd_cfg, var, value);
        if (!prefixcmp(var, "diff.")) {
@@@ -317,15 -312,6 +317,15 @@@ static void emit_rewrite_diff(const cha
        const char *new = diff_get_color(color_diff, DIFF_FILE_NEW);
        const char *reset = diff_get_color(color_diff, DIFF_RESET);
        static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT;
 +      const char *a_prefix, *b_prefix;
 +
 +      if (diff_mnemonic_prefix && DIFF_OPT_TST(o, REVERSE_DIFF)) {
 +              a_prefix = o->b_prefix;
 +              b_prefix = o->a_prefix;
 +      } else {
 +              a_prefix = o->a_prefix;
 +              b_prefix = o->b_prefix;
 +      }
  
        name_a += (*name_a == '/');
        name_b += (*name_b == '/');
  
        strbuf_reset(&a_name);
        strbuf_reset(&b_name);
 -      quote_two_c_style(&a_name, o->a_prefix, name_a, 0);
 -      quote_two_c_style(&b_name, o->b_prefix, name_b, 0);
 +      quote_two_c_style(&a_name, a_prefix, name_a, 0);
 +      quote_two_c_style(&b_name, b_prefix, name_b, 0);
  
        diff_populate_filespec(one, 0);
        diff_populate_filespec(two, 0);
@@@ -527,20 -513,13 +527,20 @@@ const char *diff_get_color(int diff_use
  
  static void emit_line(FILE *file, const char *set, const char *reset, const char *line, int len)
  {
 -      int has_trailing_newline = (len > 0 && line[len-1] == '\n');
 +      int has_trailing_newline, has_trailing_carriage_return;
 +
 +      has_trailing_newline = (len > 0 && line[len-1] == '\n');
        if (has_trailing_newline)
                len--;
 +      has_trailing_carriage_return = (len > 0 && line[len-1] == '\r');
 +      if (has_trailing_carriage_return)
 +              len--;
  
        fputs(set, file);
        fwrite(line, len, 1, file);
        fputs(reset, file);
 +      if (has_trailing_carriage_return)
 +              fputc('\r', file);
        if (has_trailing_newline)
                fputc('\n', file);
  }
@@@ -1131,9 -1110,13 +1131,13 @@@ static void show_dirstat(struct diff_op
                /*
                 * Original minus copied is the removed material,
                 * added is the new material.  They are both damages
-                * made to the preimage.
+                * made to the preimage. In --dirstat-by-file mode, count
+                * damaged files, not damaged lines. This is done by
+                * counting only a single damaged line per file.
                 */
                damage = (p->one->size - copied) + added;
+               if (DIFF_OPT_TST(options, DIRSTAT_BY_FILE) && damage > 0)
+                       damage = 1;
  
                ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc);
                dir.files[dir.nr].name = name;
@@@ -1423,7 -1406,6 +1427,7 @@@ static struct builtin_funcname_pattern 
                        "\\|"
                        "^\\(.*=[ \t]*\\(class\\|record\\).*\\)$"
                        },
 +      { "php", "^[\t ]*\\(\\(function\\|class\\).*\\)" },
        { "python", "^\\s*\\(\\(class\\|def\\)\\s.*\\)$" },
        { "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" },
        { "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" },
@@@ -1461,14 -1443,6 +1465,14 @@@ static const char *diff_funcname_patter
        return NULL;
  }
  
 +void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b)
 +{
 +      if (!options->a_prefix)
 +              options->a_prefix = a;
 +      if (!options->b_prefix)
 +              options->b_prefix = b;
 +}
 +
  static void builtin_diff(const char *name_a,
                         const char *name_b,
                         struct diff_filespec *one,
        char *a_one, *b_two;
        const char *set = diff_get_color_opt(o, DIFF_METAINFO);
        const char *reset = diff_get_color_opt(o, DIFF_RESET);
 +      const char *a_prefix, *b_prefix;
  
 -      a_one = quote_two(o->a_prefix, name_a + (*name_a == '/'));
 -      b_two = quote_two(o->b_prefix, name_b + (*name_b == '/'));
 +      diff_set_mnemonic_prefix(o, "a/", "b/");
 +      if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
 +              a_prefix = o->b_prefix;
 +              b_prefix = o->a_prefix;
 +      } else {
 +              a_prefix = o->a_prefix;
 +              b_prefix = o->b_prefix;
 +      }
 +
 +      a_one = quote_two(a_prefix, name_a + (*name_a == '/'));
 +      b_two = quote_two(b_prefix, name_b + (*name_b == '/'));
        lbl[0] = DIFF_FILE_VALID(one) ? a_one : "/dev/null";
        lbl[1] = DIFF_FILE_VALID(two) ? b_two : "/dev/null";
        fprintf(o->file, "%sdiff --git %s %s%s\n", set, a_one, b_two, reset);
@@@ -2351,10 -2315,8 +2355,10 @@@ void diff_setup(struct diff_options *op
                DIFF_OPT_CLR(options, COLOR_DIFF);
        options->detect_rename = diff_detect_rename_default;
  
 -      options->a_prefix = "a/";
 -      options->b_prefix = "b/";
 +      if (!diff_mnemonic_prefix) {
 +              options->a_prefix = "a/";
 +              options->b_prefix = "b/";
 +      }
  }
  
  int diff_setup_done(struct diff_options *options)
                DIFF_OPT_SET(options, EXIT_WITH_STATUS);
        }
  
 -      /*
 -       * If we postprocess in diffcore, we cannot simply return
 -       * upon the first hit.  We need to run diff as usual.
 -       */
 -      if (options->pickaxe || options->filter)
 -              DIFF_OPT_CLR(options, QUIET);
 -
        return 0;
  }
  
@@@ -2511,6 -2480,10 +2515,10 @@@ int diff_opt_parse(struct diff_options 
        else if (!strcmp(arg, "--cumulative")) {
                options->output_format |= DIFF_FORMAT_DIRSTAT;
                DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
+       } else if (opt_arg(arg, 0, "dirstat-by-file",
+                          &options->dirstat_percent)) {
+               options->output_format |= DIFF_FORMAT_DIRSTAT;
+               DIFF_OPT_SET(options, DIRSTAT_BY_FILE);
        }
        else if (!strcmp(arg, "--check"))
                options->output_format |= DIFF_FORMAT_CHECKDIFF;
@@@ -3424,7 -3397,10 +3432,7 @@@ static void diffcore_skip_stat_unmatch(
  
  void diffcore_std(struct diff_options *options)
  {
 -      if (DIFF_OPT_TST(options, QUIET))
 -              return;
 -
 -      if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER))
 +      if (options->skip_stat_unmatch)
                diffcore_skip_stat_unmatch(options);
        if (options->break_opt != -1)
                diffcore_break(options->break_opt);
diff --combined diff.h
index 1ca4f4628473c940fa0399b23f8da5c92a424dd5,c34688881d7ea80ecbe2ff1b3cca880f6f06f598..a49d865bd9cb0fa5ff27ccad7049074afb0002e9
--- 1/diff.h
--- 2/diff.h
+++ b/diff.h
@@@ -64,6 -64,7 +64,7 @@@ typedef void (*diff_format_fn_t)(struc
  #define DIFF_OPT_RELATIVE_NAME       (1 << 17)
  #define DIFF_OPT_IGNORE_SUBMODULES   (1 << 18)
  #define DIFF_OPT_DIRSTAT_CUMULATIVE  (1 << 19)
+ #define DIFF_OPT_DIRSTAT_BY_FILE     (1 << 20)
  #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)
  #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)
  #define DIFF_OPT_CLR(opts, flag)    ((opts)->flags &= ~DIFF_OPT_##flag)
@@@ -160,8 -161,6 +161,8 @@@ extern void diff_tree_combined(const un
  
  extern void diff_tree_combined_merge(const unsigned char *sha1, int, struct rev_info *);
  
 +void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b);
 +
  extern void diff_addremove(struct diff_options *,
                           int addremove,
                           unsigned mode,