Merge branch 'sb/diff-color-move'
authorJunio C Hamano <gitster@pobox.com>
Tue, 3 Oct 2017 06:42:49 +0000 (15:42 +0900)
committerJunio C Hamano <gitster@pobox.com>
Tue, 3 Oct 2017 06:42:49 +0000 (15:42 +0900)
The output from "git diff --summary" was broken in a recent topic
that has been merged to 'master' and lost a LF after reporting of
mode change. This has been fixed.

* sb/diff-color-move:
diff: correct newline in summary for renamed files

1  2 
diff.c
diff --combined diff.c
index 4da0714cb5c4147defe9bb59685cf0f68c63bdc0,0c604726c06b07c2cd17bbdf05dc669ae92e5ae4..69f03570adf6cf2c3642aea1fb0dba5011ef966f
--- 1/diff.c
--- 2/diff.c
+++ b/diff.c
@@@ -21,7 -21,6 +21,7 @@@
  #include "string-list.h"
  #include "argv-array.h"
  #include "graph.h"
 +#include "packfile.h"
  
  #ifdef NO_FAST_WORKING_DIRECTORY
  #define FAST_WORKING_DIRECTORY 0
@@@ -358,6 -357,9 +358,6 @@@ int git_diff_ui_config(const char *var
                return 0;
        }
  
 -      if (git_color_config(var, value, cb) < 0)
 -              return -1;
 -
        return git_diff_basic_config(var, value, cb);
  }
  
@@@ -402,6 -404,9 +402,6 @@@ int git_diff_basic_config(const char *v
                return 0;
        }
  
 -      if (starts_with(var, "submodule."))
 -              return parse_submodule_config_option(var, value);
 -
        if (git_diff_heuristic_config(var, value, cb) < 0)
                return -1;
  
@@@ -459,9 -464,11 +459,9 @@@ static struct diff_tempfile 
         * If this diff_tempfile instance refers to a temporary file,
         * this tempfile object is used to manage its lifetime.
         */
 -      struct tempfile tempfile;
 +      struct tempfile *tempfile;
  } diff_temp[2];
  
 -typedef unsigned long (*sane_truncate_fn)(char *line, unsigned long len);
 -
  struct emit_callback {
        int color_diff;
        unsigned ws_rule;
        int blank_at_eof_in_postimage;
        int lno_in_preimage;
        int lno_in_postimage;
 -      sane_truncate_fn truncate;
        const char **label_path;
        struct diff_words_data *diff_words;
        struct diff_options *opt;
@@@ -853,38 -861,6 +853,38 @@@ static int shrink_potential_moved_block
        return rp + 1;
  }
  
 +/*
 + * If o->color_moved is COLOR_MOVED_PLAIN, this function does nothing.
 + *
 + * Otherwise, if the last block has fewer alphanumeric characters than
 + * COLOR_MOVED_MIN_ALNUM_COUNT, unset DIFF_SYMBOL_MOVED_LINE on all lines in
 + * that block.
 + *
 + * The last block consists of the (n - block_length)'th line up to but not
 + * including the nth line.
 + *
 + * NEEDSWORK: This uses the same heuristic as blame_entry_score() in blame.c.
 + * Think of a way to unify them.
 + */
 +static void adjust_last_block(struct diff_options *o, int n, int block_length)
 +{
 +      int i, alnum_count = 0;
 +      if (o->color_moved == COLOR_MOVED_PLAIN)
 +              return;
 +      for (i = 1; i < block_length + 1; i++) {
 +              const char *c = o->emitted_symbols->buf[n - i].line;
 +              for (; *c; c++) {
 +                      if (!isalnum(*c))
 +                              continue;
 +                      alnum_count++;
 +                      if (alnum_count >= COLOR_MOVED_MIN_ALNUM_COUNT)
 +                              return;
 +              }
 +      }
 +      for (i = 1; i < block_length + 1; i++)
 +              o->emitted_symbols->buf[n - i].flags &= ~DIFF_SYMBOL_MOVED_LINE;
 +}
 +
  /* Find blocks of moved code, delegate actual coloring decision to helper */
  static void mark_color_as_moved(struct diff_options *o,
                                struct hashmap *add_lines,
                }
  
                if (!match) {
 -                      if (block_length < COLOR_MOVED_MIN_BLOCK_LENGTH &&
 -                          o->color_moved != COLOR_MOVED_PLAIN) {
 -                              for (i = 0; i < block_length + 1; i++) {
 -                                      l = &o->emitted_symbols->buf[n - i];
 -                                      l->flags &= ~DIFF_SYMBOL_MOVED_LINE;
 -                              }
 -                      }
 +                      adjust_last_block(o, n, block_length);
                        pmb_nr = 0;
                        block_length = 0;
                        continue;
                }
  
                l->flags |= DIFF_SYMBOL_MOVED_LINE;
 -              block_length++;
  
                if (o->color_moved == COLOR_MOVED_PLAIN)
                        continue;
                        }
  
                        flipped_block = (flipped_block + 1) % 2;
 +
 +                      adjust_last_block(o, n, block_length);
 +                      block_length = 0;
                }
  
 +              block_length++;
 +
                if (flipped_block)
                        l->flags |= DIFF_SYMBOL_MOVED_LINE_ALT;
        }
 +      adjust_last_block(o, n, block_length);
  
        free(pmb);
  }
@@@ -1414,7 -1391,7 +1414,7 @@@ static void remove_tempfile(void
  {
        int i;
        for (i = 0; i < ARRAY_SIZE(diff_temp); i++) {
 -              if (is_tempfile_active(&diff_temp[i].tempfile))
 +              if (is_tempfile_active(diff_temp[i].tempfile))
                        delete_tempfile(&diff_temp[i].tempfile);
                diff_temp[i].name = NULL;
        }
@@@ -1541,7 -1518,7 +1541,7 @@@ static void emit_rewrite_diff(const cha
  
  struct diff_words_buffer {
        mmfile_t text;
 -      long alloc;
 +      unsigned long alloc;
        struct diff_words_orig {
                const char *begin, *end;
        } *orig;
@@@ -1994,6 -1971,8 +1994,6 @@@ static unsigned long sane_truncate_line
        unsigned long allot;
        size_t l = len;
  
 -      if (ecb->truncate)
 -              return ecb->truncate(line, len);
        cp = line;
        allot = l;
        while (0 < l) {
@@@ -2583,7 -2562,6 +2583,7 @@@ static void show_stats(struct diffstat_
        }
  
        print_stat_summary_inserts_deletes(options, total_files, adds, dels);
 +      strbuf_release(&out);
  }
  
  static void show_shortstats(struct diffstat_t *data, struct diff_options *options)
@@@ -2839,7 -2817,7 +2839,7 @@@ static void show_dirstat_by_line(struc
                         * bytes per "line".
                         * This is stupid and ugly, but very cheap...
                         */
 -                      damage = (damage + 63) / 64;
 +                      damage = DIV_ROUND_UP(damage, 64);
                ALLOC_GROW(dir.files, dir.nr + 1, dir.alloc);
                dir.files[dir.nr].name = file->name;
                dir.files[dir.nr].changed = damage;
@@@ -3721,6 -3699,7 +3721,6 @@@ static void prep_temp_blob(const char *
                           const struct object_id *oid,
                           int mode)
  {
 -      int fd;
        struct strbuf buf = STRBUF_INIT;
        struct strbuf template = STRBUF_INIT;
        char *path_dup = xstrdup(path);
        strbuf_addstr(&template, "XXXXXX_");
        strbuf_addstr(&template, base);
  
 -      fd = mks_tempfile_ts(&temp->tempfile, template.buf, strlen(base) + 1);
 -      if (fd < 0)
 +      temp->tempfile = mks_tempfile_ts(template.buf, strlen(base) + 1);
 +      if (!temp->tempfile)
                die_errno("unable to create temp-file");
        if (convert_to_working_tree(path,
                        (const char *)blob, (size_t)size, &buf)) {
                blob = buf.buf;
                size = buf.len;
        }
 -      if (write_in_full(fd, blob, size) != size)
 +      if (write_in_full(temp->tempfile->fd, blob, size) < 0 ||
 +          close_tempfile_gently(temp->tempfile))
                die_errno("unable to write temp-file");
 -      close_tempfile(&temp->tempfile);
 -      temp->name = get_tempfile_path(&temp->tempfile);
 +      temp->name = get_tempfile_path(temp->tempfile);
        oid_to_hex_r(temp->hex, oid);
        xsnprintf(temp->mode, sizeof(temp->mode), "%06o", mode);
        strbuf_release(&buf);
@@@ -4009,7 -3988,7 +4009,7 @@@ static void diff_fill_oid_info(struct d
                        }
                        if (lstat(one->path, &st) < 0)
                                die_errno("stat '%s'", one->path);
 -                      if (index_path(one->oid.hash, one->path, &st, 0))
 +                      if (index_path(&one->oid, one->path, &st, 0))
                                die("cannot hash %s", one->path);
                }
        }
@@@ -5272,6 -5251,7 +5272,7 @@@ static void show_mode_change(struct dif
                        strbuf_addch(&sb, ' ');
                        quote_c_style(p->two->path, &sb, NULL, 0);
                }
+               strbuf_addch(&sb, '\n');
                emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY,
                                 sb.buf, sb.len, 0);
                strbuf_release(&sb);
@@@ -5289,7 -5269,6 +5290,7 @@@ static void show_rename_copy(struct dif
        emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY,
                                 sb.buf, sb.len, 0);
        show_mode_change(opt, p, 0);
 +      strbuf_release(&sb);
  }
  
  static void diff_summary(struct diff_options *opt, struct diff_filepair *p)
                        strbuf_addf(&sb, " (%d%%)\n", similarity_index(p));
                        emit_diff_symbol(opt, DIFF_SYMBOL_SUMMARY,
                                         sb.buf, sb.len, 0);
 +                      strbuf_release(&sb);
                }
                show_mode_change(opt, p, !p->score);
                break;